类中的析构函数
Destructor in class
我创建了一个类,并根据Andrew Koenig和Barbara E. Moo编写的教科书《Accelerated c++》
析构函数的工作是在对象消失时做任何应该做的清理工作。通常这种清理涉及释放构造函数已经分配的资源,比如内存。
我正试图写一个析构函数,但我对所有浮在那里的代码感到困惑。有时像这样的简单解构器使用~MyIntArray() {}
,有时在{}
之间有东西。
在花括号里放东西的规则是什么?它只是容器,例如列表,数组,向量,指针需要放在花括号之间(这些是我在代码示例中看到的东西)。
如果需要的话,这是我的类class msgInfo
{
public:
msgInfo();
msgInfo(int, int, int, std::string, std::list<int>);
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
规则1:
c++ 03中的三规则或c++ 11中的五规则。
如果你的类需要用户定义的复制构造函数或复制赋值操作符,那么它很可能需要用户定义的析构函数。
你什么时候需要这三个?
- 当你的类有动态分配的指针成员,你需要维护每个成员的生命周期与另一个实例成员的生命周期分开。例如:
char *
成员 - 资源管理时。例如:打开文件句柄,互斥锁等。
规则2:
如果你的类打算用于派生,你需要多态删除对象,那么你必须在基类中标记析构函数为virtual
。
好吧,如果你动态分配资源(新等),那么在析构函数中你想要释放它们(删除),在你的情况下,因为你所有的成员都不是动态分配的,你的析构函数可以是空的(或不存在)。
另一个值得注意的是,如果你最终实现了析构函数,并且你打算让别人继承你的类,你应该把它设为虚的。
在c++程序中提供析构函数是一个很好的编程实践,即使没有明确的需要。在您的代码中,您可能没有任何动态内存分配,因此提供的析构函数只是~MyIntArray() {}
,内部没有任何代码。
请同时阅读维基百科关于c++中的三法则的文章。
http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
如果您不提供析构函数,编译器将为您提供一个。这个自动生成的析构函数将正确调用所有类数据成员的析构函数,比如payload
等。
如果除此之外不需要做任何事情,那么就不需要显式地提供析构函数。或者,一个空的也同样有效。
另一方面,如果构造函数分配了一些资源(例如,连接到数据库),那么通常需要在析构函数中放入一些代码来释放该资源(例如,断开与数据库的连接)。这是用于防止资源泄漏的标准c++习惯用法。
你的类没有任何需要在析构函数中处理的资源:每种类型都是内置的(`int) or handles its own resources (
std::string ,
std::list ')。因此不需要实现自己的析构函数。编译器将提供一个等价于空花括号的值
如果你的类有需要处理的资源,你需要实现你自己的:动态分配的对象,句柄或连接到套接字,数据库,引用计数等。
实现空析构函数可能有意义的一种情况是,当您有一个打算从其派生并以多态方式使用的类时。在这种情况下,需要一个虚拟析构函数(有很多关于这个的帖子),并且通常的做法是提供一个空的实现,以便派生类型在没有资源可处理时不必自己实现它。
virtual ~Foo() {}
这样的类不需要非平凡析构函数(一个,"东西在花括号之间")。
在析构函数中,必须释放"手动"分配的资源。例如:
- 如果在构造函数中有
new/new[]
,并且需要在析构函数 中释放该内存 - 如果你在构造函数中打开了一个文件,在析构函数中关闭它
- 如果你在构造函数中锁定了一个互斥对象,在析构函数中解锁它
诸如此类。
同样,当对象被析构时,您可能需要实现一些额外的逻辑。这取决于你想做什么
析构函数的定义,据我所知,应该是这样的:
~msgInfo() { /* free stuff */ }
另一方面,构造函数可能像这样:
msgInfo(): m_var1(0), m_var2("Initialize") { /* further initialization */ }
:
和{
之间是成员变量初始化。
:
符号并不好,因为您可能需要对对象执行delete
。
在您的代码中可能没有任何动态内存分配,因此您不需要提供析构函数。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误