0

このコードがコンパイルできないのはなぜですか? コピー コンストラクターのアクセス レベルを public に変更すると、問題なく "Foo::Foo(int)" と出力されます。「Foo instance(0);」と書くと 「Foo インスタンス = 0;」の代わりに それも大丈夫でしょう。なんで?そして、この行動のポイントは何ですか?

#include <iostream>

struct Foo
{
public:
   int i;
   Foo(int i) : i(i) { std::cout << "Foo::Foo(int) \n"; }

private:
   Foo(const Foo&) { std::cout << "Foo::Foo(const Foo&) \n"; }
};

int main()
{
   Foo instance = 0;
}
4

2 に答える 2

2

Foo instance = 0;コピーの初期化を使用します。は、非明示的なコンストラクターを使用し0てオブジェクトに変換され、次に make にコピーされます。これは以下と同等です:FooFoo(int i)instance

Foo instance = Foo(0);

これには、プライベートにしたコピー コンストラクターが必要です。

公開すると、変換コンストラクターが出力するのにコピー コンストラクターが出力しない理由は、コンパイラが最適化のためにコピーを除外できるためです。これは、コードの実行を変更する可能性のある最適化の 1 つの形式です。ただし、省略されているかどうかに関係なく、コピー コンストラクターはパブリックである必要があります。言い換えれば、コピーは省略される前に可能である必要があります。

変換コンストラクターを作成するexplicitと、コンパイルされません。

explicit Foo(int i) : i(i) { std::cout << "Foo::Foo(int) \n"; }
于 2012-11-26T20:41:44.180 に答える
1

なぜなら

Foo instance = 0;

コピーの初期化であり、アクセス可能なコピー コンストラクターが必要です。変換コンストラクターを使用して一時的なFoofromを作成し、次にコピー コンストラクターを使用して一時的なものから作成しようとします。0instanceFoo

対照的に、

Foo instance(0);

直接の初期化であり、変換コンストラクタのみが必要です。

関連:コピーと直接初期化の動作が異なる理由は何ですか?

于 2012-11-26T20:39:20.500 に答える