【问题标题】:Difference syntax to pass values to a constructor c++将值传递给构造函数c ++的差异语法
【发布时间】:2019-02-19 13:44:28
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ class oop constructor


    【解决方案1】:

    当您删除此构造函数时,class A 变得有资格进行 聚合初始化,这是由以下 花括号 语法引起的:@ 987654329@(也有这个等价形式:A obj1{5,6};,因为 C++11)

    您可以read here,这适用于您的情况,因为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);正在执行direct-initialization,并且由于[dcl.init¶17.6.2]而删除构造函数后编译失败:

    [...] 如果初始化是直接初始化 [...] 构造函数被考虑。 [...] 如果没有构造函数应用 [...] 初始化是 格式错误。


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


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


    许多人讨论了使用括号形式的初始化与大括号初始化的一般优缺点。 Scott Meyers 的 Effective Modern C++ 的第 7 条是获得全面读数的好地方。也就是说,所有brace initialization forms 的最大优势是they don't allow narrowing.

    【讨论】:

      【解决方案2】:
      A obj1={5,6};
      

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

      这可能有助于您理解:Why is list initialization (using curly braces) better than the alternatives?

      【讨论】:

      • 很好的电话@3Dave,当我看到你的评论时正在更新以澄清:)
      • 另外,不错的链接 - 我不知道大括号初始化有那么大的帮助。
      • 列表初始化是否使用某种内部构造函数调用。机制是什么?它只是用来使 c++ 的结构表现得像 c 结构吗
      猜你喜欢
      • 2018-05-09
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多