我最初发布这个只是关于析构函数的问题,但现在我正在添加对默认构造函数的考虑 . 这是原始问题:
如果我想给我的类一个虚拟的析构函数,但是与编译器生成的析构函数相同,我可以使用= default:class Widget {
上市:
virtual~Widget()=默认值;
};
但似乎我可以通过使用空定义减少键入来获得相同的效果:class Widget {
上市:
virtual~Widget(){}
};
这两种定义的行为方式有何不同?
根据此问题的回复,默认构造函数的情况似乎相似 . 鉴于析构函数“ =default
" and " {}
”之间的含义几乎没有差异,默认构造函数的这些选项之间的含义几乎没有差异吗?也就是说,假设我想创建一个类型,其中该类型的对象将被创建和销毁,为什么我要说
Widget() = default;
代替
Widget() {}
?
如果在原始帖子违反某些SO规则后扩展此问题,我深表歉意 . 为默认构造函数发布一个几乎完全相同的问题让我觉得不太理想 .
3 回答
在询问构造函数而不是析构函数时,这是一个完全不同的问题 .
如果你的析构函数是
virtual
,则差异可以忽略不计,as Howard pointed out . 但是,如果你的析构函数是非虚拟的,那么这是一个完全不同的故事 . 构造函数也是如此 .对特殊成员函数使用
= default
语法(默认构造函数,复制/移动构造函数/赋值,析构函数等)意味着与简单地执行{}
非常不同 . 对于后者,函数变为"user-provided" . 这改变了一切 .根据C 11的定义,这是一个微不足道的类:
如果您尝试默认构造一个,编译器将自动生成默认构造函数 . 复制/移动和破坏也是如此 . 因为用户没有提供任何这些成员函数,所以C 11规范认为这是一个“普通”类 . 因此,这样做是合法的,比如记忆它们的内容以初始化它们等等 .
这个:
顾名思义,这不再是微不足道的 . 它有一个用户提供的默认构造函数 . 如果它是空的并不重要;就C 11的规则而言,这不是一个微不足道的类型 .
这个:
顾名思义,这是一个微不足道的类型 . 为什么?因为你告诉编译器自动生成默认构造函数 . 因此,构造函数不是“用户提供的” . 因此,类型计算为微不足道,因为它没有用户提供的默认构造函数 .
当您添加阻止创建此类函数的成员函数时,
= default
语法主要用于复制构造函数/赋值等操作 . 但它也会触发编译器的特殊行为,因此它在默认构造函数/析构函数中也很有用 .之间的重要区别
和
是
B() = default;
定义的默认构造函数被认为是 not-user defined . 这意味着在值初始化的情况下,如完全没有使用构造函数的特殊类型的初始化将发生,对于内置类型,这将导致零初始化 . 如果是
B(){}
,则不会发生这种情况 . C标准n3337 § 8.5 / 7说例如:
可能的结果:
http://ideone.com/k8mBrd
它们都是非平凡的 .
它们都具有相同的noexcept规范,具体取决于基础和成员的noexcept规范 .
到目前为止我唯一的区别是,如果
Widget
包含一个基础或成员,其中包含一个不可访问或删除的析构函数:然后
=default
解决方案将编译,但Widget
将不是可破坏的类型 . 即如果你试图破坏一个Widget
,你'll get a compile-time error. But if you don' t,你有一个工作程序 .Otoh,如果你提供用户提供的析构函数,那么无论你是否破坏了
Widget
,事情都无法编译: