简体   繁体   中英

Copy constructor doesn't copy references

According to the topic Pushing local objects into a list

The full class:

  class Invader
    {
    public:
        Invader(const Invader&other);
        Invader();
        ~Invader();
    public:
        void Init(InvaderTypes invadertype, CIw2DImage *AlienImage);
        void Update(float dt);
        void Render();
        void SetAlienImage(CIw2DImage *image){ mImageAlien = image; }

        void        setVisible(bool show)       { Visible = show; }
        bool        isVisible() const           { return Visible; }


        Iw2DSceneGraph::CSprite         *AlienSprite;
        Iw2DSceneGraph::CAtlas          *AlienAtals;
        CIw2DImage                      *mImageAlien;
        std::list<Bullet*>              *Bullets;
        CIwFMat2D                       Transform;              // Transform matrix

        bool                             Visible;                // Sprites visible state
        bool                             Canfire;
    };


Invader::Invader()
{

}

Invader::Invader(const Invader&other)
{       // Create EnemyTop atlas
    AlienAtals = new CAtlas();
    AlienSprite = new CSprite();

    *AlienAtals = *other.AlienAtals;
    *AlienSprite = *other.AlienSprite;
}

Invader::~Invader()
{
    for (std::list<Bullet*>::iterator it = Bullets->begin(); it != Bullets->end(); ++it)
        delete *it;

    delete Bullets;
    delete AlienAtals;
    delete AlienSprite;
}


void Invader::Init(InvaderTypes invadertype, CIw2DImage *AlienImage)
{
    if (invadertype == InvaderTypes::TOP_ALIEN)
    {
        //SetAlienImage(AlienImage);
        mImageAlien = AlienImage;
        // Create EnemyTop atlas
        int frame_w = (int)(mImageAlien->GetWidth() / 2);
        int frame_h = (int)(mImageAlien->GetHeight());
        AlienAtals = new CAtlas(frame_w, frame_h, 2, mImageAlien);
        AlienSprite = new CSprite();
        AlienSprite->m_X = 0;
        AlienSprite->m_Y = 0;
        AlienSprite->SetAtlas(AlienAtals);
        AlienSprite->m_W = (float)AlienAtals->GetFrameWidth();
        AlienSprite->m_H = (float)AlienAtals->GetFrameHeight();
        AlienSprite->m_AnchorX = 0.5;
        AlienSprite->SetAnimDuration(2);
    }
    else if (invadertype == InvaderTypes::MIDDLE_ALIEN)
    {

    }
    else if (invadertype == InvaderTypes::LAST_ALIEN)
    {

    }


    Visible = true;
    Bullets = new std::list<Bullet*>();
    Canfire = true;
}

I added the objects by doing:

  list<Invader> invaders;

    int spacing = 10;
    for (int i = 0; i < 5; i++)
    {
        Invader invader;
        invader.Init(TOP_ALIEN, gameResources->getAlienImageTop());
        invader.AlienSprite->m_X = 50 + spacing;
        invaders.push_back(invader);
        spacing += 50;
    }

the usage: Right now it causes an access violation when accessing (it)

 for (list<Invader>::iterator it = invaders.begin(); it != invaders.end(); it++)
            {
                (it)->Update(FRAME_TIME);
                (it)->Render();
            }

You can see the result here in the following image: 在此处输入图片说明

First, during Invader::Init()) , you provide a copy of the pointer to AlienImage . Then when you copy the object into the std::list , you don't copy that same pointer to the new object. Further, during Invader::Invader(const Invader& other) , you are not making a copy of Invader::Bullets . This leaves both the values uninitialized causing Undefined Behavior upon access (which probably occurs in (it)->Update(FRAME_TYIME); and/or (it)->Render(); -- I can't verify since you didn't provide a MCVE .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM