3

私はコピー構築のファンではありません。何度も書きましたが、

void MyFunc(MyClass val)

それ以外の

void MyFunc(const MyClass& val)

また、値渡しクローンのデストラクタで削除されたポインタに関するバグのデバッグや、MyFunc を呼び出すたびに MyClass のすべてのメンバーをコピーしているため速度低下の発見に何時間も費やさなければなりませんでした。

したがって、コピー コンストラクターを許可したくありません。

私はあなたがクラスごとにそれらを禁止できることを知っています

private:
    MyClass(const MyClass&)

しかし、すべてのクラスでそれを行う必要はありません。

デフォルトでコピー構築をオフにするコンパイラ スイッチはありますか? 組み込みの型とポインター以外でコピーの作成を許可する必要がある理由はありますか? (これらの同じ質問がコピー課題にも当てはまります)

4

3 に答える 3

10

デフォルトでコピー構築をオフにするコンパイラスイッチはありますか?

いいえ、私は本当にないことを願っています。幸いなことに、私の知る限りでは、それは確かに事実です。

組み込み型とポインター以外でコピー構築を許可する必要がある理由はありますか?

確かに。たとえば、型に値のセマンティクスを与え、クラスのさまざまなインスタンスを同じ概念エンティティとして扱う場合です。そしてその場合、コピーを作成することは非常に便利なことであることがわかります。

一方、コピー不可能なクラスが必要な場合(これにはユースケースがあります)、コピーコンストラクターをprivate(ご自身で提案したように)宣言するか、C++11では削除済みとしてマークすることができます。 :

struct X
{
    X(X const&) = delete;
};

あなたが書くものに関して:

何度も、void MyFunc(MyClass val)代わりに書いたので、void MyFunc(const MyClass& val)バグのデバッグに何時間も費やさなければなりませんでした

間違いを犯す可能性があることは理解していますが、そこから学ぶ必要があります。次のような通常の関数を作成することもできfoo()ます。

void foo(int x) { x++; }

3そして、引数として値がである変数を渡すと、呼び出しが戻った後のその変数の値がではない理由を理解しようと何時間も誓います4。ああ、あなたは参照記号を追加するのを忘れました:

void foo(int& x) { x++; }
//          ^

これが、参照渡しをデフォルトにするコンパイラオプションが必要な理由ですか?あまり。これは、言語ルールを変更するためのオプションになります。

あなたのコンパイラが本当にあなたが望むようなスイッチを持っていて、ある日あなたがそのスイッチを使っていない他の誰かにあなたのプログラムを送るなら、想像してみてください:彼らは問題がどこにあるかを見つけるためにそれをデバッグするのに何時間かかります? ?

私のアドバイスは、経験から学び、読み書きのスキルを標準語に適応させることです。その逆ではありません。

于 2013-03-10T20:26:15.313 に答える
1

魔法のスイッチはありません。あなたはプログラミングの間違いを犯し、言語を変えたいだけです。ヒープにメモリを割り当てる場合はデフォルトのコピーコンストラクタをオーバーライドして、その動的メモリを処理する必要があります(または少なくともそうする必要があります)。または、std :: vectorやstd::auto_ptrstd::unique_ptrC ++ 11の場合)などの準備が整ったクラスを使用することもできます。

于 2013-03-10T20:25:13.437 に答える
-1

私がしていることは、クラスでコピー ctor を宣言することですが、どこにも定義しないでください。コピー ctor を使用するコードを記述すると、リンカーから未定義のシンボルが取得されます。

于 2013-03-10T20:34:16.787 に答える