2

抽象ベースSysLaserBaseから継承された多くのクラスがあります。関数addLaser()に表示されているように、すべてのレーザーをプログラムのリスト(オブジェクトへのポインターのベクトル)に追加します。これは完全に正常に機能し、完全に機能しています。作成したすべてのレーザーを循環させて、問題なくそれらの方法を使用できます。

システムからレーザーを「削除」したいときに問題が発生します。これを行うには、オブジェクトのアドレスを、基本クラスのポインターのベクトル内のすべてのアドレスと比較します。これは合法ですか?プログラムがクラッシュすることがあります。代替手段は何ですか?

ここでメソッドのコードを見つけてから、クラッシュの原因となる呼び出しの例を見つけてください。removeLaser()のコードに何か問題がありますか?単一のレーザーを取り外した後、システム全体が狂ったように動作するのはなぜですか?

関連するベクトルは基本クラスの本体にあります。

std::vector<SysLaserBase<T>*> lasers;

そして、addメソッドとremoveメソッド:

template <typename T>
void SysSystemBase<T>::addLaser(const SysLaserBase<T> &src)
{
    bool alreadyThere = 0;
    for(unsigned long i = 0; i < lasers.size(); i++)
    {
        if(&src == lasers[i])
        {
            alreadyThere = 1;
            break;
        }
    }
    if(!alreadyThere)
    {
        lasers.push_back(const_cast<SysLaserBase<T>*>(&src));
    }
    signalsOut.resize(lasers.size());
}


template <typename T>
void SysSystemBase<T>::removeLaser(const SysLaserBase<T> &src)
{
    for(typename std::vector<SysLaserBase<T>*>::iterator it = lasers.begin(); it != lasers.end(); ++it)
    {
        if((*it) == &src)
        {
            lasers.erase(it);
        }
    }
    signalsOut.resize(lasers.size());
}

このコードの呼び出し:

sys.addLaser(las0);
sys.addLaser(las1);
sys.addLaser(las2);
sys.removeLaser(las0); //removes the laser, but cycling through the lasers through the vector of base class causes a crash
sys.removeLaser(las1);
sys.removeLaser(las2); //crashes the program immediately after this call

努力してくれてありがとう:-)


返信ありがとうございます。あなたの返信によると、私はremoveLaser()をこれに変更しました:

template <typename T>
void SysSystemBase<T>::removeLaser(const SysLaserBase<T> &src)
{
    for(typename std::vector<SysLaserBase<T>*>::iterator it = lasers.begin(); it != lasers.end(); ++it)
    {
        if((*it) == &src)
        {
            lasers.erase(it);
            break;
        }
    }
    signalsOut.resize(lasers.size());
}

今は大丈夫です。ありがとう :-)

4

1 に答える 1

5

itの後に無効になりlasers.erase()ます。差出人std::vector::erase()

イテレータと、消去された要素およびそれらとコンテナの終わりの間の要素への参照は無効になります。

breakから、またはからの戻りfor値を保存しますerase()

于 2012-04-18T13:15:06.220 に答える