2016-08-26 5 views
1

デフォルトのコンストラクタがプライベートの場合、このようなC++の行はどのようにしてFoo t3 = Foo::construct(true);が機能しますか?私の前提(明らかに間違っている)は、デフォルトのコンストラクタが呼び出され、代入演算子の後に続くことです。その仮定は、デフォルトのコンストラクタがprivateであり、呼び出すことができないため、正しくないはずです。静的メソッドクラスのインスタンス化

具体的な例:t3がインスタンス化されたときに、本当に背後で起こっている

int main() { 
    //Foo t1; //Not allowed, compile error, Foo() is private 
    Foo t2(true); //Constructor, valid use 
    Foo t3 = Foo::construct(true); //It works! Why? 
    return 0; 
} 

何:

class Foo { 
private: 
    Foo() {} 
    bool bar; 
public: 
    Foo(bool t): bar(t) {} 
    static Foo construct(bool t) { 
     Foo temp; //calling private constructor; 
     temp.bar = t; 
     return temp; 
    } 
} 

そして、このクラスをインスタンス化するための試験方法は次のようになりますか?

+0

'Foo t3 = Foo :: construct(true);'はコピーを作成します(symantically)。それは何が間違っていますか? – NathanOliver

+0

@ NathanOliverコピーコンストラクタがこのケースで自動生成されるかどうかは確かに分かりませんが、それはどうでしょうか? –

+0

@πάντῥῖῖ/ 12.8 *クラス定義が明示的にコピーコンストラクタを宣言していない場合、暗黙的に宣言されます* – NathanOliver

答えて

3
Foo t3 = Foo::construct(true); //It works! Why? 

この割り当て続いinitiliazationしかしcopy initialization

1既定されていないため)場合)という名前の変数(自動静的、またはスレッドローカルTが宣言さ 非参照型のイニシャライザは の等号とそれに続く式で構成されています。

だから、この声明によると:

Tである場合はクラス型や他の のタイプのCV-修飾されていないバージョンがTまたはTから派生したクラス、非明示的なコンストラクタです Tが検査され、最適な一致が過負荷解決によって選択されます。 次に、コンストラクタを呼び出してオブジェクトを初期化します。

これ:

他方は右辺値式である場合、移動コンストラクタは オーバーロード解決により選択されたコピー、初期化時に呼び出されます。移動初期化という用語は ではありません。

あなたのケースでは、暗黙的に宣言された移動コンストラクタが使用されます。

+0

参考リンクをありがとう!私自身の言葉では、コピーコンストラクタはコンパイラによって作成され、t3のインスタンス化で使用されます。 – SyntaxRules

+0

C++と仮定11。回路図を動かすこともできますか? – SyntaxRules

+0

更新された回答を参照してください、あなたのケースでは暗黙の移動ctorが使用されています。 – Slava

2

あなたの行は、デフォルトコンストラクタまたはコピー代入演算子を呼び出しません。

constructから返された一時オブジェクトからt3をコピーコンストラクトします。

0

静的構成メソッドはクラスに属し、専用コンストラクタにアクセスできます。これは、ファクトリパターンを実装するときによく使用されます。

+0

これは便利かもしれません:http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – grae22

+0

このパターンが問題の本質ではありません働くあなたが実証しているように、それはそうです。しかし、どのように私の主な方法でt3が構築されます。どのコンストラクタを使用していますか? – SyntaxRules

関連する問題