此示例程序说明了如何根据传入的是局部变量,全局变量还是匿名变量来调用不同的构造函数。这里发生了什么?
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.
}
鉴于我可以调用
globalStr.puke()
,因此我猜测是通过调用aClass(globalStr);
,它正在创建一个名为globalStr
的本地变量,其类型为aClass
,而不是全局globalStr
。调用aClass(localStr);
会尝试执行相同的操作,但是由于localStr
已经声明为std::string
,因此无法编译。是否可以通过使用非常量表达式调用其1-arg构造函数来创建类的匿名实例?谁认为type(variableName);
应该是定义变量variableName
的可接受方法? 最佳答案
aClass(localStr); //this line does not compile
这将尝试声明一个类型为
aClass
的localStr
变量。我同意语法很糟糕,但是现在(更改标准)为时已晚。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.
这将使用
globalStr
中的main
,它与其他所有阴影实例一致。是的,我可以想到四种方式:
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.
附带说明一下,这种语法通常可能是最令人头疼的解析的原因。例如,以下语句声明一个函数
foo
,该函数返回aClass
,其中一个参数localStr
的类型为std::string
:aClass foo(std::string(localStr));
确实,这是负责您的问题的规则-如果可以将某些内容解析为有效的声明,则必须如此。这就是为什么
aClass(localStr);
是一个声明而不是由一个单独的表达式组成的语句的原因。