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

Difference syntax to pass values to a constructor c++

本文关键字:语法 c++ 构造函数 值传      更新时间:2023-10-16

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

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();
}

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

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

正如您在此处阅读的,这适用于您的情况,因为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.init¶17.6.2] 删除构造函数后,它将无法编译:

[...]如果初始化是直接初始化[...] 考虑构造函数。[...]如果没有构造函数应用 [...] 初始化为格式不正确。


在删除构造函数之前,A obj1={5,6};在执行复制列表初始化时调用它的语法相同。


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


许多人讨论了使用括号形式的初始化与大括号初始化的一般优缺点。获得全面读数的好地方是斯科特·迈耶斯(Scott Meyers(的有效现代C++的第7项。也就是说,所有大括号初始化形式的最大优点是它们不允许缩小

A obj1={5,6};

这是对对象使用列表初始化,即使没有定义 2 参数构造函数,这也是完全有效的。

这可能有助于您理解:为什么列表初始化(使用大括号(比替代方案更好?