joh*_*ell 5 c++ destructor c++11
在Bjarne Stroustrup的“ C ++编程语言(第4版)”的第17.6节(生成默认操作)中,提到了这一点:
如果程序员声明了某个类的复制操作,移动操作或析构函数,则不会为该类生成任何复制操作,移动操作或析构函数。
因此,我很困惑为什么SubObj在此程序中调用析构函数:
#include <iostream>
using namespace std;
class SubObj {
public:
~SubObj() {
cout << "SubObj Destructor called" << endl;
}
};
class Obj {
private:
SubObj so;
public:
Obj() {};
Obj(const Obj& o) {};
};
int main() {
Obj();
cout << "Program end" << endl;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++编译时,我得到以下输出:
$ ./a.out
SubObj Destructor called
Program end
Run Code Online (Sandbox Code Playgroud)
根据我的理解,我希望默认的析构函数Obj不会自动生成,因为我为定义了复制操作Obj。因此,我希望不会破坏的SubObj成员,Obj因为没有的析构函数Obj。
因此,我想知道:即使没有析构函数,对象成员也会自动销毁吗?还是为此示例自动生成了析构函数?
编辑:
在本书的稍后部分(17.6.3.4)中,当提到一个示例时,Bjarne提到:
我们定义了副本分配,因此我们还必须定义析构函数。该析构函数的原因可能是
=default,它所要做的就是确保成员pos已被取消样式化,否则,如果未定义副本分配,则无论如何都会这样做。
根据到目前为止的答案,听起来似乎Bjarne可能在这个问题上是错的。
书中的那句话措辞不佳/错误。
当然,如果提供复制构造函数,则仍会生成析构函数。如果不是,您的程序将无法编译。
如果提供自己的析构函数,则不会生成析构函数。不一定要这样,而且您不能有两个。
另外,无论您的析构函数做什么,成员都将被销毁。析构函数允许您在对象(和子对象)生存期的常规规则之上执行“额外”工作。永远不会有该SubObj成员不会被销毁的风险。
Bjarne的措词本来可以更好。什么
如果程序员声明了某个类的复制操作,移动操作或析构函数,则不会为该类生成任何复制操作,移动操作或析构函数。
可能更准确(但仍然是错误的,有关完整规则,请参见下面的链接)
如果程序员声明了某个类的复制操作,移动操作或析构函数,则不会为该类分别生成复制操作,移动操作或析构函数。
这意味着,如果您声明任何这些特殊成员函数,则编译器将不会添加其自己的版本。如果声明了复制构造函数,则它不会停止析构函数,而只会停止复制构造函数(并在C ++ 11 +中移动)。仅定义析构函数可阻止编译器生成析构函数。要查看所有规则,请参见:编译器为一个类创建的所有成员函数是什么?这是否一直发生?
| 归档时间: |
|
| 查看次数: |
275 次 |
| 最近记录: |