33

このようなコピーコンストラクタの実装にはいくつかの欠点がありますか?

Foo::Foo(const Foo& i_foo)
{
   *this = i_foo;
}

私が覚えているように、ある本では代入演算子からコピーコンストラクターを呼び出してよく知られたスワップトリックを使用することが推奨されていましたが、なぜか覚えていません...

4

3 に答える 3

23

はい、それは悪い考えです。ユーザー定義型のすべてのメンバー変数は、最初に初期化され、すぐに上書きされます。

そのスワップトリックはこれです:

Foo& operator=(Foo rhs) // note the copying
{
   rhs.swap(*this); //swap our internals with the copy of rhs
   return *this;
} // rhs, now containing our old internals, will be deleted 
于 2010-04-14T16:15:18.497 に答える
11

operator=()コンストラクターを呼び出すことには、潜在的な欠点と潜在的な利点の両方があります。

欠点:

  • コンストラクターは、値を指定するかどうかに関係なく、すべてのメンバー変数operator=を初期化してから、それらを再度初期化します。これにより、実行が複雑になります。これによりコードに許容できない動作が発生する場合については、賢明な判断を下す必要があります。

  • コンストラクターとoperator=緊密に結合されます。オブジェクトをインスタンス化するときに必要なことはすべて、オブジェクトをコピーするときにも実行されます。繰り返しますが、これが問題であるかどうかを賢く判断する必要があります。

利益:

  • コードベースの複雑さが軽減され、保守が容易になります。繰り返しになりますが、このゲインの評価については賢明です。2つの文字列メンバーを持つ構造体がある場合、それはおそらく価値がありません。一方、50人のデータメンバーがいるクラス(おそらくそうすべきではありませんが、それは別の投稿の話です)または互いに複雑な関係を持つデータメンバーがある場合は、1つだけにすることで多くのメリットがあります2つ以上の代わりにinit関数。
于 2010-04-14T16:32:13.827 に答える
4

あなたはスコットマイヤーズの効果的なC++、アイテム12:「オブジェクトのすべての部分をコピーする」を探しています。その要約は次のように述べています。

  • 関数をコピーするには、オブジェクトのすべてのデータメンバーとその基本クラスのすべての部分を必ずコピーする必要があります。
  • コピー機能の1つを他の機能の観点から実装しようとしないでください。代わりに、両方が呼び出す3番目の関数に共通の機能を配置します。
于 2010-04-14T16:08:31.333 に答える