做一些奇怪的事情的c ++匿名构造函数

时间:2016-02-02 22:44:31

标签: c++ anonymous default-constructor

此示例程序显示如何调用不同的构造函数,具体取决于是传入局部变量,全局变量还是匿名变量。这是怎么回事?

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的{​​{1}}类型的局部变量,被用来代替全球aClass。调用globalStr会尝试执行相同的操作,但无法编译,因为aClass(localStr);已经声明为localStr。是否可以通过使用非常量表达式调用其1-arg构造函数来创建类的匿名实例?谁决定std::string应该是一种可接受的方式来定义名为type(variableName);的变量?

1 个答案:

答案 0 :(得分:12)

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

这会尝试声明名为aClass的{​​{1}}类型的变量。语法很糟糕,我同意,但现在[改变标准]已经太迟了。

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,这与每个其他阴影实例一致。

  

是否可以通过使用非常量表达式调用其1-arg构造函数来创建类的匿名实例?

是的,我可以想到四种方式:

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)); 是一个声明而不是由一个单独的表达式组成的声明。