6

私は興味深い問題に遭遇しました。クラスで満たされたベクトルを返すC++の関数があります。ベクトルが返されると、ベクトルの要素である各クラスのデコンストラクターが呼び出されます。

問題は明らかです。クラスがポインタを指す場所でデータが破棄され、オブジェクトが破棄されるとポインタが解放されます。ベクトルがヒープ上ではなくスタック上にあるため、デコンストラクターが呼び出されると想定することしかできません。

したがって、問題は次のとおりです。

関数からベクトルを破棄せずに返し続ける方法はありますか?または、関数への入力としてベクトルを返すためにポインターを渡す必要がありますか?

4

3 に答える 3

4

を使用して、ヒープ上に何でも作成できますnew。関数が終了するとすぐにスタックオブジェクトが破棄されるため、関数からスタックオブジェクトへの参照を渡さないでください。

関数がでベクトルを返すようにしたい場合は、ベクトル内のオブジェクトがコピーコンストラクターを実装していることを確認してください(おそらく代入演算子も、それについてはわかりません)。それで、三つのルールを忘れないでください。

于 2011-02-13T15:00:51.670 に答える
1

C ++ 11は、右辺値参照を使用して問題を解決する必要があります。正直なところ、私は自分で試したことはありませんが、読んだことから、あなたがやろうとしていることを正確に実行し、ベクトルを破棄して再作成せずに(そのベクトルによって割り当てられたメモリを新しいベクトルに渡すことによって)返します。新しいベクターに独自のメモリを作成させ、古いものからコンテンツをコピーします)。

于 2012-06-01T02:26:41.877 に答える
0

C++ベクトルヒープに割り当てられます。値でベクトルを返すと、すべての要素のコピーを使用して新しいベクトルが作成され、元の要素が破棄されます。

コピーコンストラクターを適切に定義していないようです。例えば:

class ThisIsWrong
{
public:
    ThisIsWrong()
    {
        i = new int;
        *i = rand();
    }
    ~ThisIsWrong()
    {
        delete i;
        i = nullptr;
    }

    int value() const
    {
        return *i;
    }

private:
    int* i;
};

void foo()
{
    vector<ThisIsWrong> wronglets;
    wronglets.push_back(ThisIsWrong());
    return wronglets;
}

void main()
{
    vector<ThisIsWrong> w = foo();
    w[0].value(); // SEGFAULT!!
}

コピーおよび割り当てコンストラクターを削除するか(これにより、ランタイムではなくコンパイルエラーになります)、またはそれらを適切に実装する必要があります。

于 2016-10-24T11:20:45.653 に答える