对Vector <type *>迭代器感到困惑

时间:2019-01-19 21:00:02

标签: c++ vector

我有一个具有虚拟cGameObject函数的基类update。我希望有许多派生的游戏对象,每个对象都有自己特定的update函数。

我想将派生的游戏对象添加到向量中并对其进行迭代以调用其每个更新方法。

我的迭代器有什么问题?

//In Header file
std::vector <cGameObject*> vGameObjs;
std::vector <cGameObject*>::iterator Iter;
cGameObject *AGameObj;

/In cpp file - add object pointer to vector
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);

//Iterator Crashing??
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
    //Call Each Objects Update() method here?
    }

运行此命令时,它将引发异常:读取访问冲突。 _Mycont是nullptr。

不确定该怎么办。

error thrown 类应用程序类的标题:

#ifndef _H_AGK_TEMPLATE_
#define _H_AGK_TEMPLATE_

// Link to GDK libraries
#include "AGK.h"
#include "Brickbat.h"
#include "BrickBall.h"
#include "cGameObject.h"
#include <vector>

#define DEVICE_WIDTH 1024
#define DEVICE_HEIGHT 768
#define DEVICE_POS_X 32
#define DEVICE_POS_Y 32
#define FULLSCREEN false

// used to make a more unique folder for the write path
#define COMPANY_NAME "BitMaNip:Play"

// Global values for the app
class app
{
    public:

        // constructor
        app() { memset ( this, 0, sizeof(app)); }

        // main app functions - mike to experiment with a derived class for this..
        void Begin( void );
        int Loop( void );
        void End( void );

    private:
        //Vector of GameObject Pointers;
        std::vector <cGameObject*> vGameObjs;
        //Iterator of GameObjects
        std::vector <cGameObject*>::iterator Iter;


        BrickBat *MyBat;
        BrickBall *MyBall;

        cGameObject *AGameObj;


};

extern app App;

#endif

// Allow us to use the LoadImage function name
#ifdef LoadImage
 #undef LoadImage
#endif

标题的cpp文件     //包含     #include“ template.h”     #include“ cGameObject.h”     #include

// Namespace
using namespace AGK;

app App;

void app::Begin(void)
{
    agk::SetVirtualResolution (DEVICE_WIDTH, DEVICE_HEIGHT);
    agk::SetClearColor( 151,170,204 ); // light blue
    agk::SetSyncRate(60,0);
    agk::SetScissor(0,0,0,0);

    //Test
    /*BrickBall = agk::CreateSprite(0);
    agk::SetSpriteSize(BrickBall, 64, 64);
    agk::SetSpriteColor(BrickBall, 255, 255, 255, 255);
    xPos = (DEVICE_WIDTH - 64) / 2;
    yPos = (DEVICE_HEIGHT - 64) / 2;
    agk::SetSpritePosition(BrickBall, xPos , yPos  );
    xDir = 1;
    yDir = 1;
    iSpeed = 8;*/



    MyBat = new BrickBat(128, 32, (1024-128)/2, 768-64, 0);

    AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
    vGameObjs.push_back(AGameObj);

    MyBall = new BrickBall(64, 512, 384, 1, 1, 0);

    AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
    vGameObjs.push_back(AGameObj);

}

int app::Loop (void)
{
    agk::Print( agk::ScreenFPS() );

    if (agk::GetRawKeyState(37) == 1)
    {
        MyBat->MoveLeft();
    }

    if (agk::GetRawKeyState(39) == 1)
    {
        MyBat->MoveRight();
    }

    MyBat->Update();
    MyBall->Update();
    MyBall->Collided(MyBat->iGetBatID());


    for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
    {
        //(*Iter)->Update();
        //(*Iter)->Collided(MyBat->iGetBatID());
    }

派生类

包括“ cGameObject.h”

BrickBall类:公共cGameObject { 私人的:

bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause;    //in case game is paused

公开:     BrickBall(int iSize,int xPos,int yPos,bool bHori,bool bVert,int ImageID);     虚拟void Update()覆盖;     virtual void Collided(int OtherSpriteToCheck)覆盖; };

    agk::Sync();

    return 0; // return 1 to close app
}


void app::End (void)
{

}

基类:

#pragma once
class cGameObject
{
protected:
    bool bInit = false;
    int iSprID;
    int iImageID;
    int iXPos;
    int iYPos;
    int iAngle;
    int iAlpha;
    int iWidth;
    int iHeight;
    int iColour;

    //Movement
    float fDeltaX;
    float fDeltaY;

    //Animation
    int iAniType;   //Type of animation
                    //0 = No Animation
                    //1 = Repeating Loop of Frames (All image is animation)
                    //2 = 

    int iFrameW;        //Width of Animation Frame
    int iFrameH;        //Height of Animation frame
    int iFPS;       //Animation Delay
    int iNumFrames; //Number of animation frames
    int iAniCount;  //Frame Counter

public:
    // set up default for constructor
    cGameObject(int width = 16, int height = 16, int xPos = 0, int yPos = 0, int ImageID = 0);

    void SetPosition(int ixPos, int iyPos);
    void SetSize(int iWidth, int iHeight);
    void SetWidth(int Width);
    void SetAngle(int iAngle);
    void SetTransparency(int iAlpha);
    void SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames);

    virtual void Collided(int OtherSpriteToCheck) {};

    virtual void Update() {};

    int iGetWidth();
    int iGetHeight();
    int iGetX();
    int iGetY();
    int iGetSprID();

    ~cGameObject();
};

基类cpp

    #include "cGameObject.h"
#include "agk.h"


void cGameObject::SetAngle(int iAngle)
{
    if (bInit == true)
    {
        if (iAngle > 0 && iAngle < 359)
        {
            agk::SetSpriteAngle(iSprID, iAngle);
        }
    }
}

//cGameObject::cGameObject(int width, int height, int xPos, int yPos, const char * szImageFile)
cGameObject::cGameObject(int width, int height, int xPos, int yPos, int ImageID)
{
    bInit = true;
    iImageID = 0;
    /*if (std::strlen(szImageFile) > 0)
    {
        iImageID = agk::LoadImage(szImageFile);
        if (iImageID < 1)
        {
            bInit = false;
        }
    }*/
    iColour = agk::MakeColor(255, 255, 255);

    //init animation code
    iAniType = 0;   //Type of animation
    iFrameW = 64;       //Width of Animation Frame
    iFrameH = 64;       //Height of Animation frame
    iFPS = 10;      //Animation Delay
    iNumFrames = 1; //Number of animation frames
    iAniCount = 0;  //Frame Counter


    iSprID = agk::CreateSprite(iImageID);
    if (iSprID < 1)
    {
        bInit = false;
    }
    else
    {
        agk::SetSpriteSize(iSprID, width, height);
        agk::SetSpritePosition(iSprID, xPos, yPos);
        fDeltaX = 4.0;
        fDeltaY = 4.0;

    }

}



void cGameObject::SetPosition(int ixPos, int iyPos)
{
    if (bInit == true)
    {
        agk::SetSpritePosition(iSprID, ixPos, iyPos);
    }
}

void cGameObject::SetSize(int iWidth, int iHeight)
{
    if (bInit == true)
    {
        if (iWidth > 0 && iWidth < 1024 && iHeight > 0 && iHeight < 1024)
        {
            agk::SetSpriteSize(iSprID, iWidth, iHeight);
        }
    }
}

void cGameObject::SetWidth(int Width)
{
    if (bInit == true)
    {
        agk::GetSpriteWidth(Width);
    }
}

void cGameObject::SetTransparency(int iAlpha)
{
    if (bInit == true)
    {
        if (iAlpha > 0 && iAlpha < 256)
        {
            agk::SetSpriteTransparency(iSprID, iAlpha);
        }
    }
}

void cGameObject::SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames)
{
    //Animation
    iAniType = Type;
    iFrameW = FrameW;       //Width of Animation Frame
    iFrameH = FrameH;       //Height of Animation frame
    iFPS = FPS;             //Animation Delay
    iNumFrames = NumFrames; //Number of animation frames
    iAniCount = 0;          //Frame Counter

    agk::SetSpriteAnimation(iSprID, iFrameW, iFrameH, iNumFrames);

    if (iAniType > 0)
    {
        agk::PlaySprite(iSprID, iFPS);
    }
}


int cGameObject::iGetWidth()
{
    if (bInit == true)
    {
        return agk::GetSpriteWidth(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetHeight()
{
    if (bInit == true)
    {
        return agk::GetSpriteHeight(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetX()
{
    if (bInit == true)
    {
        return agk::GetSpriteX(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetY()
{
    if (bInit == true)
    {
        return agk::GetSpriteY(iSprID);
    }
    else
    {
        return 0;
    }
}

int cGameObject::iGetSprID()
{
    if (bInit == true)
    {
        return iSprID;
    }
    else
    {
        return 0;
    }
}

cGameObject::~cGameObject()
{
    if (bInit == true)
    {
        agk::DeleteSprite(iSprID); 
    }
}

派生类标题:

#include "cGameObject.h"

class BrickBall: public cGameObject
{
private:

    bool bHoriDir;
    bool bVertDir;
    int iSpeed;
    bool bPause;    //in case game is paused


public:
    BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
    virtual void Update() override;
    virtual void Collided(int OtherSpriteToCheck) override;
};

派生类cpp

#include "BrickBall.h"

BrickBall::BrickBall(int Size, int xPos, int yPos, bool bHori, bool bVert, int ImageID):cGameObject(Size, Size, xPos, yPos, ImageID)
{
    iWidth = Size;
    iHeight = Size;
    iXPos = xPos;
    iYPos = yPos;
    bHoriDir = bHori;
    bVertDir = bVert;
    /*iSprID = agk::CreateSprite(0);
    agk::SetSpriteColor(iSprIdx, 255, 255, 255, 255);
    //agk::SetSpriteSize(iSprIdx, iSize, iSize);
    agk::SetSpriteSize(iSprIdx, 64, 64);
    //agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
    agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
    bInit = true;*/
    iSpeed = 8;

}

void BrickBall::Update()
{
    if (bInit==true)// && BatID > 0)
    {
        //Move Ball
        agk::SetSpriteColor(iSprID, 100, 100, 100, 255);

        agk::PrintC("BallX:");
        agk::Print(iXPos);

        if (bHoriDir == 1)  //Right
        {
            iXPos = iXPos + iSpeed;
            if (iXPos > 1024 - iWidth)
            {
                bHoriDir = 0;
            }
        }
        else
        {
            iXPos = iXPos - iSpeed;
            if (iXPos < 0)
            {
                bHoriDir = 1;
            }
        }

        if (bVertDir == 1)  //down
        {
            iYPos = iYPos + iSpeed;
            if (iYPos > 768 - 64)
            {
                bVertDir = 0;
            }
        }
        else
        {
            iYPos = iYPos - iSpeed;
            if (iYPos < 0)
            {
                bVertDir = 1;
            }
        }

        agk::SetSpritePosition(iSprID, iXPos, iYPos);

        //END Move Ball
        //Bat2Ball Collisions
        /*if (agk::GetSpriteCollision(iSprID, BatID))
        {
            //We have collided. 
            //As Ball is bigger than the gap below the bat must have hit top or sides
            //so just flip the vertcal direction
            if (bVertDir == 1)
            {
                bVertDir = 0;
            }
        }*/
    }

}

void BrickBall::Collided(int OtherSpriteToCheck)
{
    if (agk::GetSpriteCollision(iSprID, OtherSpriteToCheck))
    {
        if (bVertDir == 1)
        {
            bVertDir = 0;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我不知道您的错误的原因,但是我得到了这个确切的错误,因为我有一个向量迭代器,然后更新了向量,然后尝试取消引用迭代器(例如access * myIterator)。我是C ++的新手,但似乎如果您在获得迭代器后更改了集合,则该迭代器将不再有效。您需要将迭代器指向任何位置。