Der*_*son 50 c++ default-constructor
我正在准备我的CPP考试,其中一个问题是:你能否删除默认的类构造函数,如果是,那么这样做的原因是什么?好的,显然你可以这样做:
class MyClass
{
public:
MyClass() = delete;
};
Run Code Online (Sandbox Code Playgroud)
但我不明白你为什么要这样做?
Que*_*tin 75
考虑以下课程:
struct Foo {
int i;
};
Run Code Online (Sandbox Code Playgroud)
此类是聚合,您可以使用以下所有三个定义创建实例:
int main() {
Foo f1; // i uninitialized
Foo f2{}; // i initialized to zero
Foo f3{42}; // i initialized to 42
}
Run Code Online (Sandbox Code Playgroud)
现在,假设您不喜欢未初始化的值以及它们可能产生的未定义行为.您可以删除默认构造函数Foo
:
struct Foo {
Foo() = delete;
int i;
};
Run Code Online (Sandbox Code Playgroud)
Foo
仍然是聚合,但只有后两个定义有效 - 第一个定义现在是编译时错误.
Arn*_*rah 46
删除默认构造函数有几个原因.
= delete
是一个样式的东西,正如@HolyBlackCat所说,但它通过告诉客户端代码只用参数调用构造函数来澄清你的意图.如果第二个陈述不清楚,请考虑以下示例:
class A
{
public:
//A() = delete;
A(int, int) {};
};
Run Code Online (Sandbox Code Playgroud)
如果您现在尝试调用默认构造函数,则会出现类似于(GCC 7.2)的错误:
错误:没有匹配函数来调用'A :: A()'
但是,如果您使用the取消注释该行= delete
,那么您将获得以下内容:
错误:使用已删除的函数'A :: A()'
这明确表明,人们试图使用已删除的构造函数与其他错误进行比较,这有点不清楚.
多个默认选择
当默认或未初始化状态有多个选项时,删除类的默认构造函数是个好主意.例如,假设我有一个班级,
template<typename F>
class Polynomial;
Run Code Online (Sandbox Code Playgroud)
表示场上的多项式,F
.在这种情况下,多项式的默认值有很多选择.一个可能是加法下的多项式的同一性,即零,但我们也可以有乘法同一性,统一.这取决于用户打算如何推断该类以及如何使用它.
没有默认选择
另一个值得注意的情况是,在没有多个默认状态可能有意义的情况下,我们没有.例如,假设我们有一个表示流形或曲面的类.
那是Manifold()
什么?它是一个空的空间,没有任何东西,没有表面,没有距离或公制的概念.但是将它看作一种流形是没有意义的,而是像拓扑空间那样更通用的东西.
所以,在这种情况下,我也会选择删除默认构造函数.
有时候不打算对类进行实例化.
到目前为止尚未提及的一个例子是"特质"类.例如,考虑一下std::char_traits
,虽然标准没有说它的默认构造函数需要删除,但是它的默认构造函数没用,因为类本身是空的,它的所有函数都是静态的,不需要实例化为使用它提供的类型别名.
Trait类通常只用于支持其他类(通常是其他模板类),因此删除它们的默认构造函数通常是有意义的 - 强化它们只是一个帮助类型并且不应该像它一样使用的概念一个东西.
归档时间: |
|
查看次数: |
6609 次 |
最近记录: |