13

次のようなクラスがあるとします。

class Foo {
public:
    Foo(int);

    Foo(const Foo&);

    Foo& operator=(int);

private:
    // ...
};

これらの 2 つの行はまったく同じですか、それとも微妙な違いがありますか?

Foo f(42);

Foo f = 42;

編集:元の質問で Foo コンストラクターを「明示的」にすることで、問題を混乱させました。私はそれを削除しましたが、回答に感謝します。

また、コピーが簡単な操作ではないことを明確にするために、コピー コンストラクターの宣言も追加しました。

私が本当に知りたいのは、C++ 標準によると、「Foo f = 42」は Foo(int) コンストラクターを直接呼び出すのか、それともコピー コンストラクターが呼び出されるのかということです。

fasih.ahmed には私が探していた答えがあるようです (間違っていない限り)。

4

2 に答える 2

20
class Foo {
public:
    Foo(explicit int);

    Foo& operator=(int);
};

それは無効です。構文は次のとおりです。

class Foo {
public:
    explicit Foo(int);

    Foo& operator=(int);
};

違いは、明示的に前に置くと、変換コンストラクターを暗黙的な変換に使用できないことです。

Foo f(10); // works
Foo f = 10; // doesn't work

上記は、そこで宣言した代入演算子とは関係ありません。これは初期化であるため使用されません (コンストラクターのみが使用されます)。以下は、代入演算子を使用します。

Foo f;
f = 10;

そして、Foo のデフォルトのコンストラクタ (引数を取らないもの) を使用します。


編集:質問者は、質問を特定の方法に変更しました

Foo f = 1; // called "copy initialization" 
Foo f(1);  // called "direct initialization"

同じだ。答えは、それらが次のものと同等であるということです。

Foo f(Foo(1));
Foo f(1);

int を取る変換コンストラクターが keyword で宣言されていない場合に限りexplicit、そうでない場合、最初のエラーはコンパイラ エラーです (上記を参照)。コンパイラは、最初のケースで Foo のコピー コンストラクターに渡された一時的なものを除外 (最適化) することができます。これには特に、目に見えるコピー コンストラクターが含まれます。

于 2008-12-16T21:09:28.877 に答える
9
Foo f = 42;

このステートメントは、値「42」の一時オブジェクトを作成します。

Foo f(42);

このステートメントは値を直接割り当てるため、関数呼び出しが 1 つ少なくなります。

于 2008-12-16T20:53:07.303 に答える