12

これは、次のようなコンストラクターでクラスを作成するとどうなるかを正しく理解するための簡単な質問です。

class A
{
  public:
    A() {}
};

デフォルトのコンストラクターは既に定義されているため生成されないことはわかっていますが、コピーおよび代入コンストラクターはコンパイラによって生成されます。つまり、これを防ぐためにプライベート コピー コンストラクターとプライベート代入演算子を宣言する必要がありますか?

class A
{
  private:
    // needed to prevent automatic generation?
    A( const A& );
    A& operator=( const A& );
  public:
    A() {}
};
4

3 に答える 3

15

はい、独自のデフォルト コンストラクターを宣言しても、コピー コンストラクターとコピー代入演算子は引き続き作成されます。

これらの作成は、クラス定義で独自のコピー コンストラクターまたはコピー代入演算子をそれぞれ宣言した場合にのみ抑制されます。

独自のコピー コンストラクターと、コンパイラーが提供するコピー コンストラクターの両方を使用できることに注意してください。

struct A {
  A() { }
  A(A const&, int foo); 
}; // compiler declares a copy constructor now

// make the second parameter have a default argument
// now this constructor is a copy constructor too. 
inline A::A(A const&, int foo = 0) {

}

int main() {
  A a;
  A b = a; // ambiguity between compiler's one and our custom one!
}

ただし、標準では、コンパイラがこのコードを受け入れることを許可していますが、その効果は未定義の動作を持つのと似ています。プログラムの形式は正しくありませんが、そのプログラムには警告/エラーは必要ありません。(初期の GCC バージョンではこのコードは拒否されませんが、最近のバージョンでは拒否されます)。

于 2010-03-04T16:10:46.350 に答える
14

はい。コピー コンストラクター、代入演算子、およびデストラクターは、他のコンストラクターおよび演算子に関係なく常に作成されます。

1つを無効にしたい場合は、そこにあるもので完璧です. それもかなり一般的です。

于 2010-03-04T16:10:30.577 に答える
3

コピーと代入を無効にしたい場合は、private コピー コンストラクターと代入演算子 (boost::noncopyableは既製のもの) を持つクラスから継承することをお勧めします。

1) 繰り返しのタイピングが減る。

2) 自己文書化 (できれば)。

3)これらの操作を呼び出すことができないことをより強力にチェックします(クラス自体も友人もコピーを作成できません-リンカーエラーではなくコンパイラーが発生します)。

4)デフォルトのコンストラクターを非表示にしません:)

#include <boost/noncopyable.hpp>

class X : boost::noncopyable
{
};

int main()
{
    X a, b;     //has default constructor
    //X c(a);   //but can't be copied
    //a = b;    //or assigned
}
于 2010-03-04T21:02:02.267 に答える