0

以下の例では問題があります。最後の行で「中止が呼び出されました」というエラーが発生しています。なぜこれが必要なのかわかりません。

この場合、わかりやすくするために abc->def の代わりに (*abc).def を使用しています。

#include <iostream>
#include <string>
#include <vector>

class branch
{
    public:
        unsigned short n;
        std::vector<branch> branches;

        branch left()
        {
            return branches.at(0);
        }
};

void main()
{
    branch trunk = branch();
        trunk.n = 0;
        branch b1, b2;
        b1.n = 0;
        b2.n = 5;
        b1.branches.push_back(b2);
        trunk.branches.push_back(b1);

    branch* focus1 = &(trunk.branches.at(0));
    branch* focus3 = &(trunk.left());

    std::cout<<trunk.left().branches.at(0).n<<std::endl; // ok
    std::cout<<(*focus1).branches.at(0).n<<std::endl; // ok
    std::cout<<(*focus1).left().n<<std::endl; // ok
    std::cout<<(*focus3).branches.at(0).n<<std::endl; // problem
}
4

1 に答える 1

6

このコードの問題はtrunk.left()、ブランチへの参照ではなく、ブランチのコピーを返すことです。その結果、focus3ポインターは、そのコード行の実行が終了した直後にクリーンアップされる一時オブジェクトを指しています。その結果、最後の行で逆参照を試みるとfocus3、ガベージ データへのポインターをたどることになり、クラッシュが発生します。

これを修正するleftには、ブランチへの参照を返すかfocus3、一時的な参照の有効期間を参照の有効期間に延長する const 参照を作成します。

于 2011-01-05T23:52:58.620 に答える