2012-01-12 63 views
0

这里有两类区别与参数的不

class A 
{ 
    std::string s; 
public: 
    A() { prn("A constructor"); } 
    A(std::string s) : s(s) { prn("A not empty constructor"); } 
    A(const A&) { prn("A copy constructor"); } 
    A& operator =(const A& a) { prn("A = operator"); return *this; } 
    void p() { prn("in A"); } 
}; 

class B 
{ 
public: 
    A a; 
    B(A aa) : a(aa) { prn("B constructor"); } 
    B() { prn("B default constructor"); } 
}; 

现在下面的代码工作正常

B b(A("sa")); 
b.a.p(); 

打印:

一个不空的构造
复制构造
B构造函数
在一个

但是,如果使用一个构造函数不带参数的一些奇怪的事情发生

B b(A()); 

编译并运行,但没有输出(没有构造函数被调用)

B b(A()); 
b.a.p(); // error here 

了编译错误。那么这两个构造函数有什么区别呢?

+0

即使您可能认为自己做过,但您并未调用任何构造函数。 – 2012-01-12 20:00:36

+0

我认为你应该像A a; B b(a);如预期般运作良好。你提到的是函数decl不是对象decl。 – chinnagaja 2012-01-12 20:11:46

回答

5
B b(A()); 

这没有声明一个对象。它声明了一个名为b的函数,返回类型为B,该函数将指针返回类型为A的函数作为参数。

你想要的是:

B b = A(); 

或(感谢Kerrek):

B b((A())); 

或C++ 11:

B b {A()}; 

这有时被称为vexing parse

+3

只需'B b((A()));'会做。 [little lisp](http://stackoverflow.com/a/8839746/596781)从未伤害任何人。 – 2012-01-12 20:01:46

+0

[Another lisp reference](http://stackoverflow.com/a/6298050/636019); - ]此外,更一致的C++ 11版本将是'B b {A {}};'。 – ildjarn 2012-01-12 20:04:37

+0

被称为最痛苦的解析:http://en.wikipedia.org/wiki/Most_vexing_parse – 2012-01-12 20:05:20