私は、できるだけ多くの作業をコンパイラに任せるのが大の賛成派です。単純なクラスを書く場合、コンパイラは次のようなものを「無料で」提供できます。
- デフォルト(空)コンストラクタ
- コピーアンドムーブコンストラクタ
- デストラクタ
- 代入演算子 (
operator=
)
operator==
しかし、やなどの比較演算子は提供できないようですoperator!=
。例:
class foo
{
public:
std::string str_;
int n_;
};
foo f1; // Works
foo f2(f1); // Works
foo f3;
f3 = f2; // Works
if (f3 == f2) // Fails
{ }
if (f3 != f2) // Fails
{ }
これには正当な理由があるのでしょうか? メンバーごとの比較を実行するとなぜ問題になるのでしょうか? クラスがメモリを割り当てる場合は注意が必要ですが、単純なクラスであれば、コンパイラがこれを実行できるのではないでしょうか?
ベストアンサー1
コンパイラがデフォルトのコピー コンストラクターを提供できるのであれば、同様のデフォルトも提供できるはずだという議論には、operator==()
ある程度の理があります。この演算子に対してコンパイラ生成のデフォルトを提供しないという決定の理由は、Stroustrup が「C++ の設計と進化」(セクション 11.4.1 - コピーの制御) でデフォルトのコピー コンストラクターについて述べたことから推測できると思います。
個人的には、コピー操作がデフォルトで定義されているのは残念だと考えているため、多くのクラスのオブジェクトのコピーを禁止しています。ただし、C++ は C からデフォルトの割り当てとコピー コンストラクターを継承しており、頻繁に使用されます。
したがって、「なぜ C++ には default がないのかoperator==()
」という質問ではなく、「なぜ C++ には default 割り当てとコピー コンストラクターがあるのか」という質問であるべきであり、その答えは、これらの項目が C との下位互換性のために Stroustrup によって不本意ながら組み込まれた (おそらくこれが C++ の欠点のほとんどの原因であるが、C++ が人気を博した主な理由でもある) というものです。
私自身の目的のために、IDE で新しいクラスに使用するスニペットには、プライベート代入演算子とコピー コンストラクターの宣言が含まれているため、新しいクラスを生成するときに、デフォルトの代入およびコピー操作は取得されません。private:
コンパイラがそれらを生成できるようにするには、セクションからそれらの操作の宣言を明示的に削除する必要があります。