【问题标题】:C++ deleted constructorsC++ 删除了构造函数
【发布时间】:2018-10-11 06:50:36
【问题描述】:

假设我有这个结构:

struct F
{
    int& ref; // reference member
    const int c; // const member
    // F::F() is implicitly defined as deleted
};

这是来自 cppreference。正如我从文档中了解到的那样,F 的构造函数被认为是已删除,因为它有一个引用变量,它什么都不引用。因此,不能像这样声明F 类型的变量:F variableName;,因为会出现以下错误:struct F 中未初始化的引用成员。

我明白这一点,但是我不明白如果你甚至不能声明它的类型的变量,那么这样的结构会有什么好处。这种数据类型在某些特定情况下有用吗?

【问题讨论】:

    标签: c++ constructor deleted-functions


    【解决方案1】:

    由于F 是一个聚合,您可以使用aggregate initialization

    int a = 42;
    F f1 = {a, 13};
    
    // or
    
    F f2{a, 9};
    

    Live demo.

    一个类类型(通常是结构或联合)是一个聚合,如果它有:

    • 没有私有或受保护的非静态数据成员
    • 没有用户提供的、继承的或显式(C++17 起)构造函数(允许显式默认或删除的构造函数)(C++11 起)
    • 没有虚拟、私有或受保护(C++17 起)基类
    • 没有虚拟成员函数

    【讨论】:

    • 我会复制相关细节,特别是为什么示例中的数据类型是聚合。
    【解决方案2】:

    我明白这一点,但是我不明白如果你甚至不能声明它的类型的变量,这种结构会有什么好处。这种数据类型在某些特定情况下有用吗?

    被删除的隐式默认构造函数并不意味着你永远不能使用这种类型。这意味着您必须自己定义构造函数,因为只有您,程序员,才能知道该引用应该绑定到什么。所以编译器把它留给你,如果你忘记了,你会被通知 c'tor 被删除。

    这就是它被删除的原因,但正如人们所说,这本身并不意味着您不能按原样使用该结构。仍然可以聚合初始化它(但是,如果它有私有数据成员,则不可能,因此也要考虑这一点)。

    一个简单的用例可能是给成员取别名。例如(这是一个玩具示例,您可以改用默认成员初始化器):

    struct Point {
      double coord[3];
      double& x;
      double& y;
      double& z;
    
      Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
    };
    

    引用成员还意味着您需要为其他成员函数提供定义,以确保您的对象正确运行,因为它们使事情变得有些复杂。这就是为什么它们通常被避免。

    其他用途无法一一列举。

    【讨论】:

      猜你喜欢
      • 2019-05-07
      • 2021-04-12
      • 2013-08-19
      • 2016-01-27
      • 2014-05-30
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多