【问题标题】:Difference between constructors with parameters and without带参数和不带参数的构造函数的区别
【发布时间】:2012-01-13 04:12:19
【问题描述】:

这里有两个类

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 构造函数
在A

但是如果我使用没有参数的构造函数会发生一些奇怪的事情

B b(A());

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

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

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

【问题讨论】:

  • 你没有调用任何构造函数,尽管你可能认为你已经调用了。
  • 我认为你应该像 A a;B b(a);正如预期的那样工作正常。你提到的是函数 decl 而不是对象 decl。

标签: c++ constructor


【解决方案1】:
B b(A());

这并不声明一个对象。它声明了一个名为b 的函数,返回类型为B,它接受一个指向返回类型为A 的函数的指针作为参数。

你想要的是:

B b = A();

或者(感谢Kerrek):

B b((A()));

或在 C++11 中:

B b {A()};

这有时被称为vexing parse。

【讨论】:

  • 只需B b((A())); 即可。 little lisp 从未伤害过任何人。
  • Another lisp reference ;-] 此外,更一致的 C++11 版本将是 B b{A{}};。
  • 谢谢。知道了。 B b = A();如果 B() 被声明为显式,则不会工作。但是 B b((A()));在这两种情况下都可以正常工作。
  • 编译错误应该清楚表明您将b 声明为函数,而不是类实例。我的(G++)给了:request for member a in b, which is of non-class type B(A (*)()).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
相关资源
最近更新 更多