「B-things」が「両方がポインタを持つ大きなオブジェクト」よりも長持ちしない場合、「大きなオブジェクト」が削除されたときにダングリングポインタはありません。
「クラスAの1つのインスタンス」に、これらのオブジェクトの両方がデータメンバーとして含まれている場合、それらはすべて同時に破棄されます(クラスで宣言されているのとは逆の順序ですが、ほぼ同時に)。 、したがって、ダングリングポインタが使用されないようにするのはかなり簡単なはずです。
一方、ウィリーニリーの周りの「ビッグオブジェクト」へのポインターを渡す場合は、それらを寿命が不明なさまざまな場所に格納してから、「ビッグオブジェクト」を削除します。確かに、それはノーノーです。問題は「意地悪」です。制御を維持し、大きなオブジェクトがそれを指すオブジェクトよりも長持ちすることを確認する必要があります。
たとえば、次は完全に安全です。
struct Big {
// big stuff
};
struct Little {
Little(const Big *a) : bigthing(a) {}
// stuff that uses bigthing
private:
const Big *bigthing;
};
struct Foo {
Big onlybigthing;
Little firstlittlething;
Little secondlittlething;
Foo() :
onlybigthing(),
firstlittlething(&onlybigthing),
secondlittlething(&onlybigthing)
{}
};
もちろん、のインスタンスは、それを要求し、オブジェクトの存続期間を超えてそれを格納する人に、へLittle
のポインタを渡さないことを条件とします。同様に、インスタンスのコピーを、それらを格納する可能性のある誰か(およびそれらのポインター)に渡さないようにする必要があります。Big
Foo
Foo
Little
しかし、クラスAには2つのメンバーがあると言いますが、ここでは3つ(1つとBig
2つLittle
)あります。これは、これら2つのオブジェクトの3つのインスタンスを作成すると言うためです。それが何を意味するのかわかりません。
安全なものの別の例を次に示します。
int main() {
Big big;
Little little1(&big);
Little little2(&big);
}
安全なものの3番目の例を次に示します。
struct Little {
Little(const std::shared_ptr<Big> &a) : bigthing(a) {}
// stuff that uses bigthing
private:
std::shared_ptr<Big> bigthing;
};
int main() {
std::shared_ptr<Big> big(new Big());
Little little1(big);
Little little2(big);
big.reset(); // release our shared ownership
// safely do stuff using little1 and little2
return 0;
// on exit, little2 is destroyed first, then when little1 is destroyed
// it releases the last shared ownership of the instance of `Big`,
// which is destroyed.
}