3 回答
TA贡献1797条经验 获得超4个赞
当询问构造函数时,这是一个与析构函数完全不同的问题。
如霍华德指出virtual,如果您的析构函数是,则差异可以忽略不计。但是,如果您的析构函数不是虚拟的,那就完全不一样了。构造函数也是如此。
= default对特殊的成员函数(默认构造函数,复制/移动构造函数/赋值,析构函数等)使用语法意味着与简单地做有很大的不同{}。使用后者,该功能将变为“用户提供”。这改变了一切。
根据C ++ 11的定义,这是一个琐碎的类:
struct Trivial
{
int foo;
};
如果尝试默认构造一个,则编译器将自动生成一个默认构造函数。复制/移动和销毁也是如此。因为用户没有提供任何这些成员函数,所以C ++ 11规范将其视为“琐碎的”类。因此,这样做是合法的,例如将其内容memcpy初始化以此类推。
这个:
struct NotTrivial
{
int foo;
NotTrivial() {}
};
顾名思义,这不再是琐碎的事。它具有用户提供的默认构造函数。它是否为空无关紧要;就C ++ 11的规则而言,这不能是琐碎的类型。
这个:
struct Trivial2
{
int foo;
Trivial2() = default;
};
顾名思义,这是一个琐碎的类型。为什么?因为您告诉编译器自动生成默认构造函数。因此,构造函数不是“用户提供的”。因此,该类型被认为是微不足道的,因为它没有用户提供的默认构造函数。
= default当添加阻止创建此类函数的成员函数时,该语法主要用于执行诸如复制构造函数/赋值之类的操作。但是它还会触发编译器的特殊行为,因此它在默认构造函数/析构函数中也很有用。
TA贡献1815条经验 获得超6个赞
他们都是不平凡的。
它们都具有相同的noexcept规范,具体取决于基础和成员的noexcept规范。
到目前为止,我检测到的唯一区别是,如果Widget包含具有不可访问或删除的析构函数的基或成员:
struct A
{
private:
~A();
};
class Widget {
A a_;
public:
#if 1
virtual ~Widget() = default;
#else
virtual ~Widget() {}
#endif
};
然后,=default解决方案将编译,但Widget不会是可破坏的类型。即,如果您尝试破坏Widget,则会收到编译时错误。但是,如果不这样做,您就有一个有效的程序。
Otoh,如果您提供用户提供的析构函数,则无论您是否解构a,事情都不会编译Widget:
test.cpp:8:7: error: field of type 'A' has private destructor
A a_;
^
test.cpp:4:5: note: declared private here
~A();
^
1 error generated.
- 3 回答
- 0 关注
- 5175 浏览
添加回答
举报