0

それがオブジェクトを持っている場合は、それを呼び出しましょう。配列と配列の両方に割り当てるoと、2 つの配列があり、a で o または o にアクセスしようとするとどうなりますか? 例えば:typeo *a,*b;oabdelete[] b

struct name{int a;}
name *a = new name[1];
name *b = new name[1];
name o;
a[0] = o;
b[0] = o;
delete[] b;
a[0]; // what happens here?
4

2 に答える 2

1

例では問題ありません。a[0]b[0]は異なるメモリ位置にある異なるオブジェクトであり、一方を破棄しても他方には影響しません。

これnewは赤いニシンです。次のコードは同じように機能します。

name o;
name a = o;
{
   name b = o;
}

a;

nameつまり、値によってコピーすると、完全に異なるコピーが作成されます。allなどの組み込み型にintも値セマンティクスがあります。

このコードは、o値のセマンティクスがない場合にのみ問題が発生します。たとえば、リソース ハンドルが含まれていて、リソース ハンドルを複製するためのコピー コンストラクターおよび代入演算子コードが含まれていない場合などです。

次に、コピーoすると、そのリソースで同じハンドルを持つ 2 つのオブジェクトが作成され、oのデストラクタがリソースを解放すると、ダングリング コピーが残ります。

これらの問題を回避するには、通常、すべてのクラスを値のセマンティクスを持つように設計することをお勧めします。クラスが複製できないリソースのハンドルを持っている場合、不注意によるコピーを防ぐために、クラスのコピー コンストラクターと代入演算子を無効にする必要があります。実際、リソース ハンドルは、リソース ハンドル用に設計されたクラスによって保持される必要があります。

これは、「3 のルール」(C++11 以降では「5 のルール」または「0 のルール」) と呼ばれることもあります。

于 2015-04-23T00:03:31.613 に答える