繁体   English   中英

用一个从一个派生类到另一个派生类的指针交换向量元素

[英]swapping vector element with a pointer from one derived class to another

我有一个国际象棋游戏,最初是使用stl列表存储国际象棋的棋子,为了更好的性能,我将它们切换为矢量。 我知道向量不支持多态性,因此要解决此问题,我存储的是<Unit *>而不是<Unit>的向量。 我所有的棋子对象(典当,Rook,Bishop等)都从Unit类继承。

但是,向量和堆损坏似乎仍然存在问题。 我想我已经将其追溯到以下功能:

Unit *ChessGame::PromoteUnit(Unit *_oldUnit, UnitType _newType)
{

vector<Unit *> &army = (_oldUnit->m_gameColor == WHITE) ? m_whiteArmy : m_blackArmy;
Unit *newUnit = NULL;

for (unsigned int i = 0; i < army.size(); ++i)
{
    if (army[i]->m_subId == _oldUnit->m_subId)
    {
        if (_newType == QUEEN && _oldUnit->m_gameColor == WHITE)
        {
            newUnit = new Queen(*_oldUnit);
            newUnit->ActiveTexture_(m_textureMan->TextureId_(WhiteQueen));
        }
        else if (_newType == KNIGHT && _oldUnit->m_gameColor == WHITE)
        {
            newUnit = new Knight(*_oldUnit);
            newUnit->ActiveTexture_(m_textureMan->TextureId_(WhiteKnight));
        }
        else if (_newType == QUEEN && _oldUnit->m_gameColor == BLACK)
        {
            newUnit = new Queen(*_oldUnit);
            newUnit->ActiveTexture_(m_textureMan->TextureId_(BlackQueen));
        }
        else if (_newType == KNIGHT && _oldUnit->m_gameColor == BLACK)
        {
            newUnit = new Knight(*_oldUnit);
            newUnit->ActiveTexture_(m_textureMan->TextureId_(BlackKnight));
        }

        newUnit->m_wasPawn = true;
        delete army[i];
        army[i] = newUnit;
        break;
    }
}

m_selectedUnit = newUnit;

return newUnit;
}

由于指针只有4个字节,无论指针指向什么,这是为什么在这样的情况下stl向量仍然会有问题? 我的Pawn对象的大小比被提升为Knight或Queen的大小大8个字节,也许可以解释我遇到的奇怪的内存错误。 当我备份自己的回合历史记录并点击我的降级功能以撤消升级时:

Unit *ChessGame::DemoteUnit(Unit *_oldUnit, UnitType _newType)
{
COUT("ChessGameManager::_DemoteUnit(Unit *, UnitType)");

vector<Unit *> &army = (_oldUnit->m_gameColor == WHITE) ? m_whiteArmy : m_blackArmy;
Unit *newUnit = NULL;

for (unsigned int i = 0; i < army.size(); ++i)
{
    if (army[i]->m_subId == _oldUnit->m_subId)
    {
        newUnit = new Pawn();
        newUnit->m_wasPawn = false;

        if (_oldUnit->m_gameColor == WHITE)
            newUnit->ActiveTexture_(m_textureMan->TextureId_(WhitePawn));

        newUnit->m_gameColor = _oldUnit->m_gameColor;
        newUnit->MobilityValid_(false);
        newUnit->Color_(RvColor::ClrWhite);
        newUnit->m_square = _oldUnit->m_square;
        newUnit->m_captured = false;
        newUnit->m_origin = _oldUnit->m_origin;
        newUnit->m_subId = _oldUnit->m_subId;
        newUnit->m_visible = true;

        //newUnit->m_square->m_unit = newUnit;

        delete army[i];
        army[i] = newUnit;
        break;
    }
}

return newUnit;
}

它实际上崩溃了:

newUnit = new Pawn();

尝试使用malloc保留堆内存时,进入new Pawn()会使它在new运算符内部崩溃。 无论如何,我认为这仍然与我对vector stl的工作原理缺乏全面的了解有关。 我知道这与我的Pawn()构造函数无关,因为它在游戏板初始化期间被调用了很多次。

我怀疑但不能从您共享的信息中证明ChessGame副本构造函数和副本赋值运算符正在对m_whiteArmym_blackArmy进行浅表复制。 (注意:如果您不提供副本构造函数或副本赋值运算符,则编译器会为您提供它们。编译器提供的副本副本会进行浅表复制。)

您违反了规则

您可以通过以下方法解决此问题:

  • 切勿复制ChessGame对象。
  • 通过以下方式执行上述操作:
    • (C ++ 11之前的版本):声明并没有定义副本构造函数和副本赋值运算符。
    • (C ++ 11):在复制构造函数和复制赋值运算符声明之后指定= delete
  • 将指针更改为智能指针(如std::shared_ptr )。,或
  • 在副本构造函数和副本分配运算符中实现深层副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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