[英]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_whiteArmy
和m_blackArmy
进行浅表复制。 (注意:如果您不提供副本构造函数或副本赋值运算符,则编译器会为您提供它们。编译器提供的副本副本会进行浅表复制。)
您可以通过以下方法解决此问题:
ChessGame
对象。 = delete
。 std::shared_ptr
)。,或
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.