将值传递给构造函数c ++的差异语法

Moh*_*raz 3 c++ oop constructor class

这里我使用两种语法将值传递给构造函数: -

class A   
{

public:
    int x,y;

    A(int a,int b) : x(a),y(b){}
    void show()
    {
        cout<<x<<" "<<y<<endl;
    }
};

int main()
{

    A obj1={5,6};//first method
    A obj2(9,10);//second method

    obj1.show();
    obj2.show();
}
Run Code Online (Sandbox Code Playgroud)

并且两者都工作正常,但是当我删除构造函数本身时,第一种方法也正常工作.请解释一下.

Rei*_*ica 7

当你删除这个构造函数时,class A 就有资格进行聚合初始化,这是由这个花括号语法引起的:( A obj1={5,6};也有这个等价形式:A obj1{5,6};自C++ 11以来)

正如您在此处所述,这适用于您的情况,因为class A它没有以下任何一项:

  1. 私有或受保护的非静态数据成员(适用于C++ 11)
  2. 用户声明的构造函数(从C++ 11开始应用到C++ 17)
  3. 用户提供的构造函数(允许显式默认或删除构造函数)(从C++ 17开始应用到C++ 20)
  4. 用户提供的,继承的或显式的构造函数(允许显式默认或删除构造函数)(从C++ 20开始应用)
  5. 用户声明或继承的构造函数
  6. 虚拟,私有或受保护(自C++ 17以来适用)基类
  7. 虚拟成员函数
  8. 默认成员初始值设定项(从C++ 11开始应用到C++ 14)

相比之下,这种语法:A obj2(9,10);执行直接初始化,并且由于[dcl.init17.6.2]而删除构造函数后无法编译:

[...]如果初始化是直接初始化 [...]构造函数被考虑.[...]如果没有构造函数适用[...]初始化是错误 的.


在删除构造函数之前A obj1={5,6};,在执行copy-list-initialization时,相同的语法正在调用它.


什么是聚合初始化?它是通过braced-init-list语法初始化聚合类型的实例(遵循上面列表的数组或结构/类).大括号内的参数必须与声明顺序中的struct/class非静态数据成员匹配.它在后来的C++版本中获得了显着的提升,因为它为语言添加了更多的语法形式.你的用法是C++ 11之前唯一存在的.={...}


许多人讨论了使用括号形式的初始化与大括号初始化的一般优缺点.获得全面读数的好地方是Scott Meyers的Effective Modern C++第7项.也就是说,所有大括号初始化形式的最重要的优点是它们不允许缩小范围.