Sign in to follow this  

Error(s) using vector in a header file

This topic is 3843 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a hard time figuring this one out. I'm defining a class that represents an explosion. I want it to contain two vectors (it used to use two arrays, I'm converting it over) which will store the sprite and mask for each frame. It looks something like this:
// CExplosion.h
#include <vector> //<-- seems to be the offending line

class CExplosion {
    // Variables, functions, etc etc
 
    // Here's where I want to define two static vectors for this class,
    // since all CExplosion objects share the same image.
    static std::vector<sBitmap*> Sprites;
    static std::vector<sBitmap*> Masks;

};

I then define CExplosion in CExplosion.cpp, which also includes <vector> in order to initialize those static variables. Here's the problem, though: when I compile, I get the following errors: Error 1 error C2039: 'exception' : is not a member of 'std' Line 23 Error 2 error C2504: 'exception' : base class undefined Line 23 And then two more of exactly the same error, both on line 150 this time. These apparently occur in the stdexcept file. Any help would be greatly appreciated on this one, I really have no idea what's going on here.

Share this post


Link to post
Share on other sites
From what you've said theres nothing that should be causing it, can you post the relevent parts of CExplosion.cpp and I'm assuming that the actual header has the include guards ;).

Are you including any other headers before the vector header in either CExplosion.h or CExplosion.cpp? If so check these headers for errors as the error messages you gave are consistent with including a header with errors in it before the std::vector header. Also try moving the vector header to the start of the file which should make the actual location of the error show up (or at least make it show up in one of your files even if its the wrong one).

[rant]
Drop the C on the classes, you know its a class and if you try to use it as anything other then a class the compiler will tell you. In addition it leads to duplicated information requiring you to make extra changes if you want make it say an abstract base class/interface at a later point in time. (since you will have to go through all the code that uses it and remove the C)
[/rant]

Share this post


Link to post
Share on other sites
Quote:
Original post by Julian90[rant]
Drop the C on the classes, you know its a class and if you try to use it as anything other then a class the compiler will tell you. In addition it leads to duplicated information requiring you to make extra changes if you want make it say an abstract base class/interface at a later point in time. (since you will have to go through all the code that uses it and remove the C)
[/rant]


Yes. I've been meaning to do this but there are a lot of such classes and I've been lazy about it. I'll get that done tonight.

Quote:

From what you've said theres nothing that should be causing it, can you post the relevent parts of CExplosion.cpp and I'm assuming that the actual header has the include guards ;)

To the second part, yep. To the first ... well ... there's not much to show.

Here's the first part of CExplosion.cpp:

#include <cmath>
#include <vector>

#ifdef DEBUG_MEMORY
#include <vld.h>
#endif

#include "constants.h"
#include "ctimer.h"
#include "cgraphic.h"
#include "ctexturefactory.h"
#include "cexplosion.h"

extern CGraphic gGraphic;



Following that are function implementations. The only truly declaration-related code in this file comes at the end, when I initialize static variables:


// Allocate memory for the arrays that will contain image data for us
std::vector<sBitmap*> CExplosion::Sprites;
std::vector<sBitmap*> CExplosion::Masks;



I don't think any of my own headers contain errors; they are used extensively throughout other portions of the program with no issues. I'm going to double-check it anyway, though.

Usually I can solve this sort of problem, but extensive google searches turned up nothing useful :(

Share this post


Link to post
Share on other sites
Odds are it's your code. You say your headers are used extensively, so there can't be any silly errors like that? How about the SCL? :D

Just post all of Explosion.h and Explosion.cpp and we can help. Everything looks fine so far, but you haven't given us much.

Share this post


Link to post
Share on other sites
I had hoped to avoid flooding the post with too much code, but since it might be something small I'll post it in its entirety. The only thing I've changed is replacing the fixed-size array with a vector instead, since it looks much cleaner.

Here is exactly what I have for CExplosion.h:

/**
* @file cexplosion.h
* @description Header file for CExplosion.cpp. This file contains the class
* and function prototypes for the CExplosion object.
* @project Fighters 1945
* @date 06/08/07
* @author Amrazek
* @version 1.0
*/




#ifndef _CEXPLOSION_
#define _CEXPLOSION_


#include <vector>
#include "cgraphic.h"
#include "csprite.h"

typedef std::vector<sBitmap*> imageList;

class CExplosion {
public:

/**
* Constructor
* @param x X coordinate of the explosion.
* @param y Y coordinate of the explosion.
* @param angle Angle of the explosion (in radians) [but stored as radians internally]
* @param velocity Velocity of the explosion.
* @param duration How long the explosion will last, in milliseconds.
* @param playExplosionSound plays the explosion.wav sound if true.
* @pre None
* @post The object is contructed.
* @return This function has no return value.
*/

CExplosion(double x, double y, double angle, double velocity, long duration, bool playExplosionSound = true);



/**
* Destructor for the CExplosion class.
* @pre None
* @post The object is destructed.
* @return This function has no return value.
*/

~CExplosion();



/**
* Function to update this explosion's animation frame and to determine
* whether or not the explosion should end ( = reached time limit )
* @pre None
* @post The object is updated.
* @return This function has no return value.
*/

void update();



/**
* Function to draw this explosion.
* @pre None
* @post The object is drawn.
* @return This function has no return value.
*/

void draw();



/**
* STATIC Function to update all explosions.
* @pre None
* @post All explosions are updated.
* @return This function has no return value.
*/

static void updateAll();



/**
* STATIC Function to draw all explosions.
* @pre None
* @post All explosions are drawn.
* @return This function has no return value.
*/

static void drawAll();



/**
* STATIC Function to destroy all explosions.
* @pre None
* @post All explosions are destroyed.
* @return This function has no return value.
*/

static void destroyAll();



/**
* STATIC Function to add an explosion image frame.
* @param sprite Pointer to an sBitmap construct with valid image data
* @param mask Pointer to an sBitmap construct with valid image data
* @pre both sprite and mask are valid pointers and contain valid data
* @post None
* @return This function has no return value.
*/

static void addFrame(sBitmap* sprite, sBitmap* mask);



/**
* Function to create a new explosion with the specified parameters.
* @param x X coordinate of the explosion.
* @param y Y coordinate of the explosion.
* @param angle Angle of the explosion (in degrees) [but stored as radians internally]
* @param velocity Velocity of the explosion.
* @param duration How long the explosion will last, in milliseconds.
* @pre Appropriate images and sound have already been loaded for this explosion.
* @post The object is created.
* @return This function has no return value.
*/

static void createExplosion(double x, double y, double angle, double velocity, long duration);



/**
* STATIC Function to delete all frames of the CExplosion object and
* release the memory they contain.
* @pre None
* @post All CExplosion frames are deleted.
* @return This function has no return value.
*/

static void deleteAllFrames();



protected:

/**
* STATIC Function to add an explosion to the list.
* @param ae A Valid CExplosion object pointer.
* @pre ae is a pointer to a valid CExplosion object not already
* in the list.
* @post ae is added to the list.
* @return This function has no return value.
*/

static void registerExplosion(CExplosion* ae);



/**
* STATIC Function to remove an explosion to the list.
* @param re A Valid CExplosion object pointer.
* @pre re is a pointer to a valid CExplosion object already
* in the list.
* @post re is removed from the list.
* @return This function has no return value.
*/

static void unregisterExplosion(CExplosion* re);



static CExplosion* pHead; // Head CExplosion object

static imageList Sprites; // Contains all sprite sBitmap objects
static imageList Masks; // Contains all masks

CTimer* myTimer; // Timer to keep track of elapsed time
CExplosion* pNext; // Next CExplosion object in the list
long myDuration; // Number of milliseconds this explosion will stay active
int myCurrentFrame; // Index of the current frame number of the explosion

double myX; // X position of the explosion
double myY; // Y position of the explosion

double myAngle; // Angle (in radians) this explosion is moving in
double myVelocity; // Velocity (in pixels per second) this explosion is moving in

long lngLastFrameUpdate; // TickCount of the last time the frame was updated
};


#endif



Likewise, this is CExplosion.cpp in its entirety:

/**
* @file CExplosion.cpp
* @description This source file contains the class and function definitions
* for the CExplosion class. This class is responsible for creating,
* managing, and releasing all CExplosion objects.
* @project Fighters 1945
* @date 06/08/07
* @author Amrazek
* @version 1.0
* @note For function documentation, please see cexplosion.h
*/




#include <vector>
#include <cmath>


#ifdef DEBUG_MEMORY
#include <vld.h>
#endif

#include "constants.h"
#include "ctimer.h"
#include "cgraphic.h"
#include "ctexturefactory.h"
#include "cexplosion.h"


extern CGraphic gGraphic;

// Constructor
CExplosion::CExplosion(double x, double y, double angle, double velocity, long duration, bool playExplosionSound) {
myX = x;
myY = y;
myAngle = angle * DEGREES_TO_RADIANS;
myVelocity = velocity;
myDuration = duration;
myCurrentFrame = 0;
registerExplosion(this);

if (playExplosionSound) {
// TODO: play sound
}

lngLastFrameUpdate = GetTickCount();
myTimer = new CTimer;
myTimer->start();
}



// Destructor
CExplosion::~CExplosion() {
delete myTimer;
unregisterExplosion(this);
}



void CExplosion::update() /* update this object */ {
if ((long)GetTickCount() - lngLastFrameUpdate > myDuration / (long)CExplosion::Sprites.size() ) {
lngLastFrameUpdate = GetTickCount();

myCurrentFrame++;

if ((size_t)myCurrentFrame == CExplosion::Sprites.size()) { // explosion now ends
delete this;
return;
}
}

// update the position of the explosion
myX = myX + myVelocity * myTimer->getElapsedTimeFactor() * cos(myAngle);
myY = myY + myVelocity * myTimer->getElapsedTimeFactor() * sin(myAngle);
}



void CExplosion::draw() /* draw this object to the screen */ {
// Get this frame's sprite
sBitmap* myImage = CExplosion::Sprites.at(myCurrentFrame);

// Get this frame's mask
sBitmap* myImageMask = CExplosion::Masks.at(myCurrentFrame);

if (myImage != NULL) {
if (!myImage->b32bit) {
if (myImageMask != NULL) {
// draw image + mask
gGraphic.hBitBltBitmap(*myImage, static_cast<int>(myX), static_cast<int>(myY), *myImageMask);
} else {
// Draw image (No mask)
gGraphic.hBitBltBitmap(*myImage, static_cast<int>(myX), static_cast<int>(myY));
}
} else {
// 32 bit image
BLENDFUNCTION bf;

bf.BlendFlags = 0;
bf.AlphaFormat = AC_SRC_ALPHA;
bf.BlendOp = AC_SRC_OVER;
bf.SourceConstantAlpha= 255;

AlphaBlend(gGraphic.getBackBufferDC(), static_cast<int>(myX), static_cast<int>(myY), myImage->width, myImage->height, myImage->ImageDC, 0, 0, myImage->width, myImage->height, bf);
}
}

}



void CExplosion::updateAll() /* update all CExplosion objects */ {
CExplosion* currentExplosion = CExplosion::pHead;
CExplosion* nextExplosion = NULL;

while (currentExplosion) {
nextExplosion = currentExplosion->pNext;
currentExplosion->update();
currentExplosion = nextExplosion;
}
}



void CExplosion::drawAll() /* draw all CExplosion objects */ {
CExplosion* currentExplosion = CExplosion::pHead;
CExplosion* nextExplosion = NULL;

while (currentExplosion) {
nextExplosion = currentExplosion->pNext;
currentExplosion->draw();
currentExplosion = nextExplosion;
}
}



void CExplosion::destroyAll() /* destroy all CExplosion objects */ {
CExplosion* currentExplosion = CExplosion::pHead;
CExplosion* nextExplosion = NULL;


while (currentExplosion) {
nextExplosion = currentExplosion->pNext;
delete currentExplosion;
currentExplosion = nextExplosion;
}
}



void CExplosion::addFrame(sBitmap* sprite, sBitmap* mask) {
if (!sprite) {
//dwrite("CExplosion: addFrame() -> Invalid sprite!");
return; // invalid
}

CExplosion::Sprites.push_back(sprite);

// we need the sprites and masks to be equal in number,
// even if the mask is not used. This makes the drawing
// routine a little simpler
if (!mask)
mask = new sBitmap;

CExplosion::Masks.push_back(mask);
}



void CExplosion::createExplosion(double x, double y, double angle, double velocity, long duration) /* create a new explosion */ {
CExplosion* newExplosion = NULL;
newExplosion = new CExplosion(x, y, angle, velocity, duration);
}



void CExplosion::registerExplosion(CExplosion* ae) /* add a CExplosion object to the list */ {
CExplosion* nextExplosion = NULL;

// is this the first element?
if (!CExplosion::pHead) {
CExplosion::pHead = ae;
ae->pNext = NULL;
return;
}

// We must find the end of the list
nextExplosion = CExplosion::pHead;

while (nextExplosion) {
// nextExplosion is valid, does it have another CExplosion linked to it?
if (!nextExplosion->pNext) {
// There's no next! We found our place
nextExplosion->pNext = ae;
ae->pNext = NULL;
break;
} else {
nextExplosion = nextExplosion->pNext;
}
}
}



void CExplosion::unregisterExplosion(CExplosion* re) /* remove a CExplosion object from the list */ {
CExplosion* prevExplosion = NULL;
CExplosion* nextExplosion = NULL;

// is re the first element?
if (re == CExplosion::pHead) {
// set the head to the next element
CExplosion::pHead = CExplosion::pHead->pNext;
return;
}

// re isn't the first element, so this will take some shuffling of pointers
nextExplosion = CExplosion::pHead;

while (nextExplosion) {
// Is the current timer the one we want to remove?
if (nextExplosion == re) {
// we need to remove nextTimer
// (prevExplosion is the explosion before this, and v->pNext is the one after)
prevExplosion->pNext = nextExplosion->pNext;
nextExplosion->pNext = NULL;
return;
} else {
// was not the one we were looking for, so move on
prevExplosion = nextExplosion;
nextExplosion = nextExplosion->pNext;
}
}
}



// Delete all frames of this explosion object
// NOTE: we do NOT destroy the images themselves! This task
// is handled by CTextureFactory. We merely remove this class's
// references to those images and reset the vectors.
void CExplosion::deleteAllFrames() {
CExplosion::Sprites.clear();
CExplosion::Masks.clear();
}



// Allocate memory for the static variable CExplosion::pHead
CExplosion* CExplosion::pHead = NULL;

// Allocate memory for the arrays that will contain image data for us
std::vector<sBitmap*> CExplosion::Sprites;
std::vector<sBitmap*> CExplosion::Masks;


Share this post


Link to post
Share on other sites

This topic is 3843 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this