私は今後のC++試験の準備をしていますが、クラスとコンストラクターに関する次の質問に出くわしました。
クラスFractionにはいくつのコンストラクターがありますか?」
class Fraction { //... public: Fraction(int numerator = 0, int denominator = 1); //... };
私はそれが1つだけだと思ったが、彼らは3つあると提案した:
Fraction();
Fraction(n);
Fraction(n, d);
または言い換えれば:
デフォルト値を持つ関数はオーバーロードされた関数ですか?
投稿された宣言に対応するコンストラクタは1つだけで、3つのオーバーロードはありません。
呼び出し
_Fraction();
Fraction(n);
_
以下と同等です:
_Fraction(0, 1);
Fraction(n, 1);
_
宣言に対応するコンストラクタは1つしかないことを確信させるもう1つの方法は、3つではなく1つのコンストラクタを定義するだけでよいということです。
デフォルト引数に関するC++ 11標準のセクションには、次のものがあります。
8.3.6デフォルト引数
1initializer-clauseがparameter-declarationthisで指定されている場合initializer-clauseがデフォルト引数として使用されます。デフォルト引数は、末尾の引数が欠落している呼び出しで使用されます。
2 [例:宣言
_void point(int = 3, int = 4);
_
int
型のゼロ、1、または2つの引数で呼び出すことができる関数を宣言します。次のいずれかの方法で呼び出すことができます。_point(1,2); point(1); point();
_最後の2つの呼び出しは、それぞれ
point(1,4)
およびpoint(3,4)
と同等です。 —例の終了]
次に主な質問です。
クラスFractionにはコンストラクタがいくつありますか?
質問を組み立てた人が、コンストラクターのセットに明示的に削除しない限りコンパイラーによって暗黙的に生成される移動コンストラクターとコピーコンストラクターを含める場合、答えはです。その場合、質問はトリックの質問です。
デフォルト値を持つ関数はオーバーロードされた関数ですか?
いいえ。オーバーロードは次のようになります
Fraction();
Fraction(int numerator);
Fraction(int numerator, int denominator);
独自の実装(定義)がありますが、デフォルトのパラメーターを持つ関数には単一の実装があります。
私はそれが1つだけだと思ったが、彼らは3つがあると示唆した...
"クラスFractionにはコンストラクタがいくつありますか?"
definite与えられたコードスニペットの答えは(言葉でthree)です。
1つの特殊なコンストラクター(呼び出しの3つのバリアントを提供)があり、コンパイラーは、delete
を使用しない場合、またはカスタム実装を提供しない場合、コピーおよび移動コンストラクターを自動的に生成します。
Fraction(int numerator = 0, int denominator = 1); // (1)
// Redundant, just for demonstration:
Fraction(const Fraction& rhs) = default; // (2)
Fraction(Fraction&& rhs) = default; // (3)
そのような試験のために、あなたが答えれば
クラスには1つのコンストラクターがあります
とにかく間違っています。あなたが答えるなら
クラスには3つのコンストラクターがあります(あなたが書いたように、それは受け入れられた答えです)
あなたはその理由を深く説明する必要があります(上で説明したように)。
口頭試験では、理由を正確にバックアップするようにお願いします。そのため、見習いテストを行います。
質問に対する答えは、次の3つのフォローアップの質問に関連しています。
明示的な定義は1つのコンストラクターのみです。コンパイラーは、呼び出しが明示的に0、1、または2つの引数を提供するかどうかに関係なく、3つの引数の呼び出しを挿入します。
'11より前では、移動コンストラクタはありません。'11では、2つの暗黙的なコンストラクタ定義Fraction(const Fraction &) noexcept
とFraction(Fraction &&) noexcept
があり、アクセス可能 cppreference をチェックします'14暗黙的に定義された移動コンストラクターの変更がある場合のルール。
あなたが得た質問は、残念ながら無邪気に見えますが、かなり技術的です。あなたのクラスがC++を単純化しすぎることを主張しないことを望みます。それはそれを学ぶための最悪の方法です。
コンストラクターの宣言は1つだけです。
反対側:
同じスコープ内の単一の名前に対して2つ以上の異なる宣言が指定されている場合、その名前はオーバーロードされていると言われます。
そのため、ここではoverloadedという用語は使用しません。