重複の可能性:
3 つのルールとは?
Array(const Array &arraytoCopy)
:size(arraytoCopy.size)
{
ptr=new int[size];
for(i=0;i<size;i++)
ptr[i]=arraytoCopy.ptr[i];
}
コピー コンストラクターを提供しないとどうなるか。
重複の可能性:
3 つのルールとは?
Array(const Array &arraytoCopy)
:size(arraytoCopy.size)
{
ptr=new int[size];
for(i=0;i<size;i++)
ptr[i]=arraytoCopy.ptr[i];
}
コピー コンストラクターを提供しないとどうなるか。
オブジェクトをコピーすると、動的に割り当てられた同じ配列を指す複数のインスタンスが作成されます。破壊時にどのインスタンスが割り当て解除を処理する必要があるかは明確ではありません。
クラスが配列を所有することになっている場合は、リソースの割り当て解除を担当します。この場合、配列の内容のコピーを作成するコピー コンストラクターと代入演算子に加えて、delete[]
それを呼び出すデストラクタが必要です。これは3 つのルールとして知られています。C++11 では、move copy および move 代入演算子も必要です。
クラスが配列を所有していない場合、おそらく最初から構築すべきではありません。たとえば、コンストラクターを介して、外部に割り当てられた配列へのポインターを受け取ることができます。
クラス内に動的に割り当てられた所有オブジェクトへの生のポインターがあるため、コピー コンストラクターとコピー代入演算子関数を適切に提供する必要があります。
以下のクラス定義を検討してください
class Array
{
public:
Array()
{
ptr = new int[10];
}
~Array(){
delete [] ptr;
}
private:
int *ptr;
};
Array の 2 つのオブジェクトをインスタンス化する場合:
Array a1, a2;
a1 = a2;
現在
、a1、a2 の破壊中a1.ptr
と同じメモリ アドレスを指しています。ptr メモリは 2 回削除されますが、これは未定義の動作です。p2.ptr
std::vector<int> int_collection_;
生のポインターを使用する代わりに、使用することをお勧めします。
class Array
{
public:
Array()
{
}
~Array(){
}
private:
std::vector<int> int_collection_;
};
クラスインスタンスのコピーを許可しない場合は、コピーコンストラクターをプライベートとして定義し、コンパイラーがこれらのケースをキャッチできるように実装を提供しないでください。
class Array
{
...
private:
Array(const Array &arraytoCopy); // not implemented
};
この場合、上記のポインタ所有権の問題について心配する必要はありません。