12

たくさんのデータメンバーがいる長いクラスがあります。そのためのコピーコンストラクターを書きたいです。ただし、独自のコピーコンストラクターを作成すると、デフォルトのコピーコンストラクターにアクセスできなくなります。

自分のコピーコンストラクターでいくつかのポインターを修復したいだけです。そのため、デフォルトのコピーコンストラクターで実行できるオブジェクトの浅いコピーが必要です。

自分のコピーコンストラクターがある場合、デフォルトのコピーコンストラクターにアクセスする可能性はありますか?

4

8 に答える 8

13

変更したくないものを構造体にラップし、それから(個人的に)派生します。コピーコンストラクターで、基本クラスのコピーコンストラクターを呼び出すだけです。

于 2012-09-14T10:57:32.287 に答える
8

いいえ、デフォルトと独自のコピーc-torの両方を持つことはできません。

ただし、この問題には2つの回避策があります。


1定義されたコピーセマンティクスを使用してポインタをクラスに囲みます

例:

class A {
public:
private:
   int trivial1;
   int trivial2;
   ...
   SomePointer  nontrivialMember;
};

class SomePointer {
public:
  SomePointer(const SomePointer&); // here the non trivial part of A copy semantics
  int* nonTrivialMember;
};

2些細なパラメータをいくつかの些細な構造で囲みます

例:

class A {
public:
   A(const A& o) : data(o.data) {
     // non trivial part
   }
private:
   struct Data {
     int trivial1;
     int trivial2;
     ...
   } data;
   int* nontrivialMember;
};

私は常に最初の解決策を選択します。

[アップデート]

私の2番目と非常によく似た3番目の解決策もあり、あなたの些細な部分を私的に継承された基本クラスで囲みます。私はまだ最初の解決策を好みます。

于 2012-09-14T10:57:35.237 に答える
4

これに対する最も簡単なアプローチは、コピーコンストラクターで手動で「修復」を実行するクラスにポインターをラップすることです。そうすれば、デフォルトのコピーコンストラクターをうまく使用できます。

于 2012-09-14T10:58:58.813 に答える
0

いいえ、ユーザー定義のコピーコンストラクターからデフォルトのコピーコンストラクターを呼び出す方法はありません。

于 2012-09-14T10:56:01.617 に答える
0

デフォルトまたは独自のいずれかを使用できますが、両方を使用することはできません。オブジェクトごとに異なる機能を選択したい場合は、その場合を処理するメンバー関数を作成するだけです。

void DeepCopy(MyClass* rhs);

例えば。

于 2012-09-14T11:00:02.410 に答える
0

独自に作成した場合、デフォルトのコピーコンストラクタにアクセスすることはできません。コンパイラはそれを生成しません。ただし、回避策があります。クラスをデータ構造とロジックに分割します。

例を参照してください:

struct Data
{
  int i;
  std::string s;

  Data(): i(), s() {}
};

class Code: private Data
{
public:

  Code() {}

  Code(const Code& rhs): Data(rhs) // Call default copy ctor
  {
     i = 42; // Your copy part
     return *this;
  }

};
于 2012-09-14T11:09:36.063 に答える
0

私の解決策は、以下に示す例のように、暗黙の(コンパイラーによって生成された)コピーコンストラクターへの不可能な呼び出しではなく、単純なmemcpy()です。

Class Foo
{
public:
   ...
   Foo (Foo & other) {
      // copies trivial part (and non-trivial part with possible wrong values)
      memcpy(this, &other, sizeof(Foo));

      // your non-trivial part here, overwrites the wrong values (if any) above.
   }
}

ただし、副作用として、memcpy()は、これらの重要な部分もコピーします。これは無駄です。重要な部分にあまり多くのスペースが含まれていない場合、私は自分の解決策を好みます。

たとえば、以下のようなクラスは、ポインタのサイズが4バイトであると仮定すると、1つのポインタの4バイトのコピーのみを浪費します。

Class Bar
{
    int x, y, z;

    // memcpy() wastes these 4 bytes copy,
    // since actual copy constructor wants a new string
    string *s;  
}
于 2014-10-20T08:06:29.427 に答える
0

これは私にとってはうまくいきました...(C ++ 11、古い標準で機能するかどうかはわかりません)なぜそれが無限ループにならないのかわかりません。

class Foo {
public:
  Foo(const Foo &orig) {
     *this = orig;
     ... exchange pointers, do own stuff
  }
于 2016-11-09T09:39:36.263 に答える