2016-02-02 4 views
6

このサンプルプログラムは、ローカル変数、グローバル変数、または匿名変数のどちらを渡すかによって、異なるコンストラクタがどのように呼び出されるかを示しています。ここで何が起こっているのですか?C++奇妙なことをする匿名のコンストラクタ

std::string globalStr; 
class aClass{ 
public: 
    aClass(std::string s){ 
    std::cout << "1-arg constructor" << std::endl; 
    } 
    aClass(){ 
    std::cout << "default constructor" << std::endl; 
    } 
    void puke(){ 
    std::cout << "puke" << std::endl; 
    } 
}; 

int main(int argc, char ** argv){ 
    std::string localStr; 
    //aClass(localStr); //this line does not compile 
    aClass(globalStr); //prints "default constructor" 
    aClass(""); //prints "1-arg constructor" 
    aClass(std::string("")); //also prints "1-arg constructor" 
    globalStr.puke(); //compiles, even though std::string cant puke. 
} 

は私がaClass(globalStr);を呼び出すことによって、それがグローバルglobalStrの代わりに使用されているタイプaClassglobalStrという名前のローカル変数を作成していることを推測している、globalStr.puke()を呼び出すことができることを考えます。 aClass(localStr);を呼び出すと同じことが試みられますが、localStrは既にstd::stringと宣言されているため、コンパイルに失敗します。 1-argコンストラクタを非定数式で呼び出すことで、クラスの匿名インスタンスを作成することは可能ですか?誰がが、variableNameという名前の変数を定義するのに許容される方法であるべきだと決めたのですか?

+0

_anonymousコンストラクタとは何ですか?私が知っていることはありません。 –

+0

[これは興味深い](http://ideone.com/eNXYvI)、なぜ 'pud()'が 'std :: string'クラスで呼び出されるのですか? –

+1

@πάνταῥεῖ、 'main'の' globalStr'の宣言によって隠されています。 – chris

答えて

12
aClass(localStr); //this line does not compile 

これはlocalStr名前付きの型aClassの変数を宣言しようとします。構文はひどいですが、私は同意しますが、それは[標準の変更]には遅すぎます。

aClass(globalStr); //prints "default constructor" 

これは、globalStrと呼ばれるものを宣言します。このglobalStr変数はグローバル変数を隠します。

aClass(""); //prints "1-arg constructor" 

これは、タイプaClassの一時オブジェクトを作成します。

aClass(std::string("")); //also prints "1-arg constructor" 

これも一時的なものです。

globalStr.puke(); //compiles, even though std::string cant puke. 

これは、シャドウイングの他のすべてのインスタンスと一致しmainglobalStr、使用します。

1-argコンストラクタを非定数式で呼び出すと、クラスの匿名インスタンスを作成できますか?

はい、私は4つの方法を考えることができます側の注意点として

aClass{localStr}; // C++11 list-initialization, often called "uniform initialization" 
(void)aClass(localStr); // The regular "discard this result" syntax from C. 
void(aClass(localStr)); // Another way of writing the second line with C++. 
(aClass(localStr)); // The parentheses prevent this from being a valid declaration. 

、この構文は、多くの場合、ほとんどの難問の解析の原因となることができます。たとえば、次のようにタイプstd::stringの一つのパラメータlocalStrで、aClassを返す関数fooを宣言します。

aClass foo(std::string(localStr)); 

確かに、それはあなたの問題の責任だ同じルールだ - 何かが有効な宣言として解析することができた場合は、それでなければなりません。そのため、aClass(localStr);は宣言であり、単独の式で構成されるステートメントではありません。

関連する問題