4

私は次のようなクラスを定義しようとしていました:

#include <library/foo.h>

class my_class {
private:
  someone_elses foo;
public:
  myclass();
  ~myclass();
  //...
};

しかし、コンパイラは失敗しました:「someone_elses型のフィールドfooにはプライベートコピーコンストラクタがあります」。これで、次の方法でこれに対処できることがわかりました。

class my_class {
private:
  someone_elses *foo;
//...
};

my_class::my_class() { foo = new someone_elses(); }
my_class::~my_class() { delete foo; }

私の質問は、オブジェクトのフィールドがアクセス可能なコピーコンストラクターを実装するかどうかをコンパイラーが気にするのはなぜですか?

4

5 に答える 5

3

最初のバージョンでは、のインスタンスをコピーしmy_classていて、表示されていない場所にいる必要がある場合は、のディープコピーを実行していますsomeone_elses

後者のバージョンでは、同じことを行うと、のインスタンスへのポインターの浅いコピーを作成しますsomeone_elses。したがって、コピーを作成するのではなく、の両方のコピーに同じインスタンスへのポインタがありますmy_class

実際にはデストラクタで削除someone_elsesしているので、あらゆる種類の問題が発生します。コピーできるようにする必要がありますsomeone_elsesが、そのクラスの作成者が非常に重要であると考えたためにコピーできなかったため、何らかの理由でコピーが許可されていないようです。

この問題にどのように対応するかは、省略した詳細に大きく依存します。のコピーを許可できない可能性がありmy_class、そのコピーコンストラクタもプライベートにする必要があります。もちろん、コンストラクターが使用されていない場合は作成されないため、これは別の場所で何かを壊します。

于 2012-05-18T16:16:25.207 に答える
2

その理由は、コピーコンストラクターが'コピーコンストラクターをmy_class呼び出すためです。意味的にはあまり意味がありませんが、someone_elses構成をコピーしないコピーコンストラクタを定義する必要があります。someone_elses

class my_class {
private:
  someone_elses foo;
public:
  my_class(const my_class& rhs) {
   // do nothing, end up with default constructed someone_elses.
  } 
  myclass();
  ~myclass();
  //...
};
于 2012-05-18T16:13:02.847 に答える
2

C ++ 03標準12.8(クラスオブジェクトのコピー)コピー構造:

各サブオブジェクトは、そのタイプに適した方法でコピーされます。

  • サブオブジェクトがクラスタイプの場合、クラスのコピーコンストラクタが使用されます。
  • サブオブジェクトが配列の場合、各要素は要素タイプに適した方法でコピーされます。
  • サブオブジェクトがスカラー型の場合、組み込みの代入演算子が使用されます。

あなたのコードは最初の要件を破っていsomeone_elsesます。あなたの場合のサブオブジェクトのコピーコンストラクターはprivate使用できないため、コンパイラーはエラーを正確に指摘します。

于 2012-05-18T16:14:45.163 に答える
1

のコピーコンストラクタはのコピーコンストラクタmy_classを呼び出すためですfoo。これはオブジェクトであり、ポインタではないため、そのコピーコンストラクタを呼び出す必要があります。

于 2012-05-18T16:11:20.070 に答える
1

オブジェクトのフィールドがアクセス可能なコピーコンストラクターを実装しているかどうかをコンパイラーが気にするのはなぜですか?

プログラムがそれを呼び出すので、my_classの暗黙のコピーコンストラクタで。検討:

int main () {
  my_class m1;
  my_class m2(m1);
}

の作成はをm2呼び出しますmy_class::my_class(const my_class&)。提供しなかった場合は、自動的に提供されます。この暗黙のコピーコンストラクタは、の各フィールドをm1の対応するフィールドにコピーするだけですm2。具体的には、をコピーする必要がありますfoo

ただし、someone_elses::someone_else(const someone_else&)はプライベートなのでコピーできませんfoo。したがって、エラー。

于 2012-05-18T16:14:08.157 に答える