【问题标题】:No constructor called? [duplicate]没有调用构造函数? [复制]
【发布时间】:2020-03-05 11:11:13
【问题描述】:

我试图理解使用 l/r 值调用的构造函数,所以我在下面创建了class A

class A {
    public :
    A()            { cout << "called default constructor" << endl ; }
    A(const A&)    { cout << "called copy constructor" << endl ; }
    A(const A&&)   { cout << "called move constructor" << endl ; }
};

在main函数中,我创建了一个实例a

int main()
{
    A a(A());
    return 0;
}

但是在实现的构造函数中没有构造函数被调用!

有什么解释吗?谢谢!

【问题讨论】:

  • 调用构造函数时使用{}A a(A())被解释为函数声明。
  • 这能回答你的问题吗? What is the purpose of the Most Vexing Parse? Clang 警告说“括号被消除歧义作为函数声明 [-Wvexing-parse]”
  • 尝试使用a作为对象,你会感到惊讶。
  • 这就是为什么你应该使用A a{A{}};

标签: c++ class constructor copy-elision


【解决方案1】:

这个

A a(A());

是一个函数声明,其返回类型为A 和一个A() 类型的参数,这是一种不带参数并返回A 的函数类型。编译器将参数隐式调整为指针类型,使其功能类似于A (*)()

要声明一个对象,你应该写要么

A a( ( A() ));

或者

A a {A()};

例如

A a( A{} );

这是一个演示程序

#include <iostream>

using namespace std;

class A {
    public :
    A()            { cout << "called default constructor" << endl ; }
    A(const A&)    { cout << "called copy constructor" << endl ; }
    A(const A&&)   { cout << "called move constructor" << endl ; }
};

int main() 
{
    A a1( ( A() ) );
    A a2( A{} );

    A a3 { A() };


    return 0;
}

它的输出是

called default constructor
called default constructor
called default constructor

注意这些对象声明中有复制省略。

例如调用你可以编写的复制构造函数

A a1;
A a2( a1 );

例如调用移动构造函数的简单方法是

A a1;
A a2( std::move( a1 ) );

【讨论】:

  • @rafix07 你是对的。:)
猜你喜欢
  • 2013-05-26
  • 1970-01-01
  • 2016-07-12
  • 2012-05-09
  • 2011-04-18
  • 1970-01-01
  • 2012-11-16
  • 2021-05-14
相关资源
最近更新 更多