复制构造函数不会复制引用

时间:2014-12-31 18:24:44

标签: c++

根据主题Pushing local objects into a list

全班:

  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;
}

我通过执行以下操作添加了对象:

  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;
    }

用法:现在它在访问(it)时会导致访问冲突

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

您可以在下图中看到结果:   enter image description here

1 个答案:

答案 0 :(得分:0)

首先,在Invader::Init())期间,您将指针的副本提供给AlienImage。然后,当您将对象复制std::list时,您不会将同一指针复制到新对象。此外,在Invader::Invader(const Invader& other)期间,您不会复制Invader::Bullets。这使得两个值都未初始化,导致访问时出现未定义行为(可能发生在(it)->Update(FRAME_TYIME);和/或(it)->Render(); - 我无法验证,因为您没有&#39 ; t提供MCVE