web-dev-qa-db-ja.com

「デフォルトコンストラクター」はコンパイラーが生成したコンストラクターを意味し、「引数なしコンストラクター」は作成したコンストラクターを意味する必要がありますか?

私にとって、「デフォルト」という言葉は、何もしないとどうなるかを意味します。ですから、私が何も書かないのであれば、「デフォルトコンストラクタ」はコンパイラが提供するものだけを参照するべきだと思います。これにより、他のメソッドに引数がない場合と同様に、「引数コンストラクターなし」は私が作成したコンストラクターを意味しますであることが明確になります。

多くの人が「デフォルトコンストラクタ」を「引数のないもの」と同じ意味で使用しているため、これが合意された規則であるとは思いません。しかし、それは他のタイプの方法には当てはまりません。私のすべてのアクセサーは「デフォルトアクセサー」とは呼ばれず、引数をとらない計算方法は「デフォルト計算」とは呼ばれません。では、なぜこれがコンストラクターと混同されるのでしょうか。片付けてもいいですか?

1
user186205

混乱する必要はありません。デフォルトのコンストラクターは、引数なしで呼び出すことができる1つ(そして1つだけ)です。他の値を指定せずにそのクラスのオブジェクトを作成すると、デフォルトで呼び出されます。公式の文言が必要な場合(§[class.ctor]/4):

クラスXのデフォルトのコンストラクターは、パラメーターがないか、関数パラメーターパックではない各パラメーターにデフォルトの引数があるクラスXのコンストラクターです。

ここでの唯一の混乱は、「デフォルトのctor」を「暗黙的に定義されたctor」を意味するために使用していることです。 2つは別々の概念です。

誰かがひどく欲しがっていたら、「デフォルト」を使用して暗黙的に定義されたctorを意味し、他の用語を引数を必要としないctorを意味するように定義できたと思いますが、少なくとも私の意見では、ずっと前にそれをしなければならなかったでしょう。今すぐ条件を変更しようとするのは少なくとも数十年遅すぎます。

6
Jerry Coffin

ここでいくつかの概念を混同していると思いますが、いくつかの重複がある可能性があります。これに言語のタグを付けなかったので、15年以上のソフトウェア専門家としての私にとって意味する単語の一般的な定義に従います。

  • 引数なしのコンストラクターは、引数をまったく受け入れないコンストラクターです。

  • デフォルトのコンストラクターは、明示的な引数なしで呼び出すことができるコンストラクターです。これは引数なしのコンストラクターである場合もあれば、デフォルトのパラメーターがある場合もあります。

  • コンパイラー生成コンストラクターは、明示的に定義されたコンストラクターがない場合にコンパイラーが作成するコンストラクターです。これは通常、引数なしのコンストラクターになります。注:C++は他のコンストラクターも生成する可能性がありますが、 C++ 11の時点ではルールはそれほど単純ではありません

私にとって、「デフォルト」という言葉は、私が何もしなかった場合に何が起こるかを意味します。

「何もしない」という意味で、「コンパイラがデフォルトのパラメータとして引数を提供しているかどうかに関係なく、引数を提供しない」という意味で同意します。

したがって、 "デフォルトコンストラクター"は、何も記述しない場合、コンパイラーが提供するコンストラクターのみを参照する必要があると思います。

プログラマーがデフォルトのコンストラクターを提供できないのはなぜですか?多くの場合、少なくともインターフェイスに関しては同等です。デフォルトのコンストラクターを提供する唯一の理由は、何もしない実装では実行されない状態を初期化するか、別のコンストラクターを呼び出すことです(つまり、this(...))。

多くの人が「デフォルトコンストラクタ」を「引数のないもの」と同じ意味で使用しているため、これが合意された規則であるとは思いません。

これも時々見ますが、意味の違いは「引数を与えなくても構築できる」ということで、私が提供した定義と一致していると思います。

しかし、それは他のタイプの方法には当てはまりません。

ここには微妙な違いがあります。私が精通しているすべての言語で、すべてのコンストラクターは関数ではありません。 「オーバーロード」という用語は両方に適用される場合がありますが、オーバーロードされた関数は、技術的には別個のエンティティであり、メソッドシグネチャは異なりますが、名前は同じです。コンストラクターは、オーバーロードされる可能性もありますが、同じものを表し、同じ責任(オブジェクトの初期化)を共有するという点で特別です。

さらに、コンストラクターは通常、クラスのインターフェースの一部ではありません。オブジェクトの作成時にコンストラクターexceptを呼び出すことはできません。コンストラクターとメソッド/関数は異なる動物であり、クラスのインターフェースについて議論するときは異なる方法で扱う必要があります。コンストラクターの呼び出しがメソッドの呼び出しに似ていることを除いて、2つのエンティティ間の比較はありません(違いは、オブジェクト参照を使用してコンストラクターを呼び出さないことです)。

2
user22815