C++删除构造函数
C++ deleted constructors
假设我有这个结构:
struct F
{
int& ref; // reference member
const int c; // const member
// F::F() is implicitly defined as deleted
};
那是来自 cppreference。正如我从文档中了解到的那样, F
的构造函数被认为已删除,因为它有一个引用变量,它不引用任何内容。所以不能像这样声明一个F
类型的变量:F variableName;
因为会出现这样的错误:uninitialized reference member in struct F
.
我理解这一点,但是我不明白如果您甚至不能声明其类型的变量,这样的结构有什么用。这样的数据类型在某些特定情况下有用吗?
I understand this however I do not understand what such structure would be good for if you cannot even declare a variable of it's type. Could such a data type be useful in some specific case?
删除隐式默认构造函数并不意味着您永远不能使用此类型。这意味着你必须自己定义构造函数,因为只有你,程序员,才能知道该引用应该绑定到什么。所以编译器将它留给你,如果你忘记了,你会收到 c'tor 被删除的通知。
这就是它被删除的原因,但正如人们所提到的,这本身并不意味着您不能按原样使用该结构。仍然可以对其进行聚合初始化(但是,如果它具有私有数据成员,则不可能,因此也需要考虑)。
一个简单的用例可能是别名成员。例如(这是一个玩具示例,您可以改用默认成员初始值设定项):
struct Point {
double coord[3];
double& x;
double& y;
double& z;
Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
};
引用成员还意味着您需要为其他成员函数提供定义以确保您的对象正确运行,因为它们使事情变得有些复杂。这就是通常避免使用它们的原因。
其他用途真的无法一一列举。
由于 F
是一个集合,您可以使用 aggregate initialization:
int a = 42;
F f1 = {a, 13};
// or
F f2{a, 9};
class 类型(通常是结构或联合)是聚合,如果它具有:
- no private or protected non-static data members
- no user-provided, inherited, or explicit (since C++17) constructors (explicitly defaulted or deleted constructors are allowed) (since C++11)
- no virtual, private, or protected (since C++17) base classes
- no virtual member functions
假设我有这个结构:
struct F
{
int& ref; // reference member
const int c; // const member
// F::F() is implicitly defined as deleted
};
那是来自 cppreference。正如我从文档中了解到的那样, F
的构造函数被认为已删除,因为它有一个引用变量,它不引用任何内容。所以不能像这样声明一个F
类型的变量:F variableName;
因为会出现这样的错误:uninitialized reference member in struct F
.
我理解这一点,但是我不明白如果您甚至不能声明其类型的变量,这样的结构有什么用。这样的数据类型在某些特定情况下有用吗?
I understand this however I do not understand what such structure would be good for if you cannot even declare a variable of it's type. Could such a data type be useful in some specific case?
删除隐式默认构造函数并不意味着您永远不能使用此类型。这意味着你必须自己定义构造函数,因为只有你,程序员,才能知道该引用应该绑定到什么。所以编译器将它留给你,如果你忘记了,你会收到 c'tor 被删除的通知。
这就是它被删除的原因,但正如人们所提到的,这本身并不意味着您不能按原样使用该结构。仍然可以对其进行聚合初始化(但是,如果它具有私有数据成员,则不可能,因此也需要考虑)。
一个简单的用例可能是别名成员。例如(这是一个玩具示例,您可以改用默认成员初始值设定项):
struct Point {
double coord[3];
double& x;
double& y;
double& z;
Point() : x(coord[0]), y(coord[1]), z(coord[2]) {}
};
引用成员还意味着您需要为其他成员函数提供定义以确保您的对象正确运行,因为它们使事情变得有些复杂。这就是通常避免使用它们的原因。
其他用途真的无法一一列举。
由于 F
是一个集合,您可以使用 aggregate initialization:
int a = 42;
F f1 = {a, 13};
// or
F f2{a, 9};
class 类型(通常是结构或联合)是聚合,如果它具有:
- no private or protected non-static data members
- no user-provided, inherited, or explicit (since C++17) constructors (explicitly defaulted or deleted constructors are allowed) (since C++11)
- no virtual, private, or protected (since C++17) base classes
- no virtual member functions