2009-04-14 4 views
10

const参照の代わりにポインタを渡すだけでコピーコンストラクタを書くことができますか? (私はかかわらず、任意の値を変更するつもりはないことを確認している場合、それは大丈夫でしょうか?)ので、同様コンストラクタをコピーする - C++

:代わりの

SampleClass::SampleClass(SampleClass* p) 
{ 
//do the necessary copy functionality 
} 

:事前に

SampleClass::SampleClass(const SampleClass& copyObj) 
{ 
//do the necessary copy 
} 

感謝を。


ありがとうございました。だから、ポインタを取り込むコンストラクタを書くと(私のコピーコンストラクタだと思う)、コンパイラはデフォルトのコピーコンストラクタを提供しています。その場合、コンストラクタ(私のコピーコンストラクタだと思います)は呼び出されず、デフォルトのコピーコンストラクタが呼び出されます。とった。それは渡す値によるために有用であることがあります場合

答えて

1

号のコピーコンストラクタはなど、ポインタでない、参照を取る必要があります

4

あなたは、引数としてポインタを取るコンストラクタを書くことができます。
しかし、コピーコンストラクタは、特定のコンストラクタに与える名前です。
引数と同じクラスの参照(好ましくはconstであるが必須ではない)をとるコンストラクタは、コピーコンストラクタと呼ばれます。

19

はい、オブジェクトへのポインタを取るコンストラクタを書くことができます。ただし、コピーコンストラクタと呼ぶことはできません。コピーコンストラクタの定義の場合、同じクラスのオブジェクトを渡す必要があります。他のものを渡しているなら、それはコンストラクタですが、コピーコンストラクタではありません。

1

定義により、コピーctorはconst参照を使用します。ポインタを取るctorの作成を止めるものは何もありませんが、参照を使用するときには存在しないいくつかの問題が発生します。たとえば、NULLポインタが渡された場合にはどうなりますか?

1

値パラメータは

1
...これは、コピーコンストラクタを呼び出します。そのパラメータのコピーを作成しますコピーコンストラクタを呼び出すことになる、コピーを作成することが必要となるため、コピーコンストラクタは、リファレンスを必要とします

あなたはそのようなコンストラクタを書くことはできますが、それは技術的にコピーコンストラクタではありません。たとえば、STLコンテナは引き続きコンパイラで生成されたコピーコンストラクタを使用します(コンパイラはコピーコンストラクタを生成しません)。

2

明示的にディセーブルにしない限り、コピーコンストラクタではなく、コンパイラはコピーコンストラクタを生成します。 NULLポインタからコンストラクタの正しいセマンティクスは何ですか?これはあなたのクラスのユーザーに何を追加しますか? (ヒント:ヒープオブジェクトから構築する場合は、ポインタを逆参照して通常のコピーコンストラクタを使用するだけです)。

1

コピーコンストラクタが暗黙のうち2例で使用されます。

  • あなたのクラスのインスタンスが関数に値によって渡された場合。
  • クラスのインスタンスが関数から値によって返されるとき。

他にも述べたように、記述されたシグネチャ(またはconstポインタ)を持つコンストラクタを書くことはできますが、上記のいずれの場合でも使用されることはありません。

-1

完全に有効なコピーコンストラクタを記述することはできますが、引き続きNULLの参照を渡すことができます。 NULLをテストできますが、コンストラクタの初期化リストを使用しない場合に限ります。

例:

MyClass::MyClass(MyClass const& MyClassCopy) 
: somevar(MyClassCopy.somevar) // <- the init list goes here. 
{ 
    // If MyClassCopy is NULL, the initialization above is doomed! 
    // However we can check for NULL in the constructor body but 
    // the initialization list must be removed ... 
    if (&MyClassCopy == NULL) throw(std::runtime_error("NULL pointer!")); 
    somevar = MyClassCopy.somevar; 
} 

// I'll now do some very dangerous programming to 
// demonstrate one way that a NULL can get through ... 
MyClass* P = NULL; 
MyClass A(*P); // Bang, you're dead! 

は、私の知る限りでは、初期化リストの中からNULLかどうかを確認する方法はありませんので、あなたが考える場合は、NULLが通過取得状況になってしまう可能性があり、あなたはそれをコンストラクタ本体でテストし、そこから初期化する必要があります。あなたはそのコードで未定義の動作を起動せずにnull参照を取得することはできません

と::演算子の注意すべき=()関数をいくつかの落とし穴があります忘れないでください...

+1

。エラーが他のコードにあるので、事実の後にNULLをテストすると便利ではありません。実際、コンパイラは、正しいプログラムで決して実行できないため、テストの 'if(&MyClassCopy == NULL)'を最適化できます。 –

+0

私は、NULLポインタの逆参照が無効な操作であることに同意し、逆参照操作の前にNULLのテストを行うのが最善です。しかし、実行時にNULLを割り当てることができるため、ほとんどのコンパイラではNULL参照を作成することができ、コンパイラがそれをチェックする方法はありません。またはNULLのテストを最適化するために、。あなたはg ++でそれを試すことができ、テストは動作します。 – Rob

+0

一瞬のリフレクションの後、あなたは正しいです、逆参照操作の前にnullをテストしなければなりません。事実後のテストは確かに未定義です。 – Rob

関連する問題