C++ 将向量元素与指针从一个派生类交换到另一个派生类

C++ 将向量元素与指针从一个派生类交换到另一个派生类,c++,pointers,stl,vector,polymorphism,C++,Pointers,Stl,Vector,Polymorphism,我有一个国际象棋游戏,最初使用stl列表来存储棋子,为了更好的性能,我将其转换为向量。我知道向量不支持多态性,所以为了解决这个问题,我存储了的向量,而不是。我的所有棋子对象(兵、车、主教等)都从Unit类继承 然而,向量和堆损坏似乎仍然存在问题。我想我已经找到了以下功能: Unit *ChessGame::PromoteUnit(Unit *_oldUnit, UnitType _newType) { vector<Unit *> &army = (_oldUnit->

我有一个国际象棋游戏,最初使用stl列表来存储棋子,为了更好的性能,我将其转换为向量。我知道向量不支持多态性,所以为了解决这个问题,我存储了
的向量,而不是
。我的所有棋子对象(兵、车、主教等)都从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;
}

当它试图使用malloc保留堆内存时,进入new Pawn()会导致它在新操作符中崩溃。无论如何,我认为这仍然与我对向量stl如何工作缺乏全面的理解有关。我知道它与我的Pawn()构造函数无关,因为它在游戏板初始化期间被多次调用。

我怀疑,但无法从您共享的信息证明,您的复制构造函数和复制赋值运算符用于
ChessGame
m_whiteArmy
m_blackArmy
进行浅层复制。(注意:如果您不提供复制构造函数或复制赋值运算符,编译器将为您提供它们。编译器提供的是浅层复制。)

你违反了法律

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

  • 从不复制
    棋盘游戏
    对象
  • 通过以下方式强制执行上述规定:
    • (C++11之前):声明和不定义复制构造函数和复制赋值运算符
    • (C++11):在复制构造函数和复制赋值运算符声明之后指定
      =delete
  • 将指针更改为智能指针(如
    std::shared_ptr
    ),或
  • 在复制构造函数和复制赋值运算符中实现深度复制

看起来像是内存错误。如果您使用的是Linux或OS X,我建议您使用valgrind来解决任何动态内存访问问题:这是仅有的两种正在运行的方法?请将您的程序缩减为演示错误的最短完整程序,并在您的问题中发布完整、简短的程序。有关更多信息,请参阅。好的,很抱歉,谢谢链接。我将致力于减少代码,然后重新生成错误。这是个好建议,我可能会在这样做之后解决它:)实际上我从来没有在我的代码中复制ChessGame类,所以我不认为这是问题所在,我只会通过指针或引用将它传递给方法或函数。我想我主要是问上面的代码在我如何尝试使用向量和基于反馈方面是否合法我猜我贴的东西看起来不错,这意味着我需要尝试去别处看看。目前我最大的问题是想弄清楚如何调试一个在“new”中出现的错误:(如果某个地方我的内存超出了范围,导致现有的连续分配被踩到,将很难知道在哪里设置断点。如果我有线程,那是一回事,但我没有。我将像Rob说的那样减少代码,然后稍后再发布我的发现。谢谢大家,感谢所有帮助!祝你好运,@RyanVanDyke-我可以建议使用两种技术来调试内存损坏:1)Linux上的valgrind(或用于Windows的类似产品)和2)testcase reduction(也称为弯刀调试)。如果您得到一个简短完整的程序失败,并且您不明白为什么,请随意提出一个新问题。我也会想到,您可以尝试审核您对
new
delete
的使用情况。看看你是否能证明这些断言:对于每一个
new
来说,只有一个
delete
;对于每个
new[]
,只有一个
delete[]
。如果您的代码路径太复杂,无法证明该断言,请尝试简化代码,或者使用
std::shared_ptr
而不是原始指针。
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();