C++构造问题求解

class A{
private:
    double re, im;
public:
    A(){}
    A(double r, double i) : re{r}, im{i} {}
    double real() { return re; }
};

int main(){
    A a(1, 2);
    A c(a);            // 这一句
    cout << c.real();
    
    A d();
    cout << d.real();    // error: request for member 'real' in 'd', which is of non-class type 'A()'
    A e{};
    cout << e.real();    // 随机的一个 double 数
 }

为什么我没有定义用一个对象去初始化另一个对象的构造器, A c(a) 还是可以呢?

另外,想问一下 () 和 {} 有什么区别呢?
{} 用来初始化,() 就是用来传参嘛?
为什么 d 和 e 行为不一样呢?

阅读 2.1k
2 个回答
  1. A c(a) 会调用 A::A(const A&),是 A 的拷贝构造函数,它与控构造函数一样,如果不自定义,编译器会自动生成一个。
  2. 使用花括号来初始化对象是 C++11 的标准:

    1. 花括号调用构造器会倾向于使用初始化列表构造,被构造会按照列表被填充;被构造对象也可以选择用 std::initializer_list 来捕获这个列表。
      http://zh.cppreference.com/w/...
      例一,基本类型可以直接填充:int a{10}
      例二,std::array 是一个结构体,内部是原生数组,也可以自动填充:std::array<int, 3> f3{1, 2, 3};
      例三,std::vector 实现了 std::initializer_list 构造:std::vector<int> v{10, 3}(得到长 2 的 vector,v[0] 是 10,v[1] 是 3)。
    2. 在上述情况匹配失败的时候,不会得到编译错误,而是会尝试匹配类的构造器,例如:std::vector<std::string> v{10, "hello"},会得到长度是 10 的 vector。因为与上面的例三对比,它匹配 vector(std::initializer_list<T>, const Allocator& alloc = Allocator()) 失败了。
      http://zh.cppreference.com/w/...
    3. C++ 中 A a() 的作用往往出人意料,它不是用空参数构造器构造一个 A 类型的对象,而是声明一个返回类型是 A,函数名是 a,并且函数参数列表空的函数;期待的空参数构造方式应该是 A a。11 标准选取了 A a{},其作用与 A a 无异。

A(a)是拷贝构造函数,你没有定义编译器会给你自动生成一个。

至于{}、()的区别,就是小括号会调用默认初始化器初始化,而大括号不会。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题