类中的析构函数

时间:2013-03-27 07:34:30

标签: c++ class destructor

我创建了一个类,并根据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;
};

8 个答案:

答案 0 :(得分:3)

规则1:

C ++ 03中的

Rule of three 或C ++ 11中的五项规则。

如果您的类需要用户定义的复制构造函数或复制赋值运算符,那么它很可能需要用户定义的析构函数。

  

您何时需要这3个中的任何一个?

  • 当您的类动态分配指针成员并且您需要维护每个实例成员的生命周期时。例如:char *成员。
  • 管理资源时。例如:打开文件句柄,互斥锁等。

规则2:

如果您的类旨在用于派生,并且您需要对对象进行多态删除,那么您必须将Base类中的析构函数标记为virtual

答案 1 :(得分:2)

好吧,如果您动态分配资源(新等等),那么在析构函数中你想要释放它们(删除),在你的情况下,由于你的所有成员都没有动态分配,你的析构函数可以为空(或不存在)。

值得一提的另一个值得注意的是,如果你最终实现了析构函数,并且计划让某人进入你的课程,那么你应该把它变成虚拟的。

答案 2 :(得分:1)

在C ++程序中提供析构函数是一个很好的编程习惯,即使没有明确需要。在您的代码中,您可能没有任何动态内存分配,因此提供的析构函数只是~MyIntArray() {}而没有任何代码。

还请阅读维基百科关于C ++中的Rule of Three的文章。

http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

答案 3 :(得分:1)

您的类没有任何需要在析构函数中处理的资源:每个类型都是内置的(`int) or handles its own resources ( std :: string , std :: list`)。所以你不需要实现自己的析构函数。编译器将提供一个等同于空括号的文件。

如果您的类具有需要处理的资源,则需要实现自己的:动态分配的对象,句柄或连接到套接字,数据库,引用计数等。

实现空析构函数可能有意义的一种情况是,当您有一个旨在从多态获取和使用的类时。在这种情况下,需要一个虚拟析构函数(有很多关于它的SO帖子),并且通常的做法是提供一个空实现,以便派生类型在没有资源可以处理时不必自己实现它。 / p>

virtual ~Foo() {}

答案 4 :(得分:1)

如果您不提供析构函数,编译器将为您提供一个析构函数。这个自动生成器析构函数将正确调用所有类的数据成员的析构函数,例如payload等。

如果您不需要做任何事情,那么您不需要明确提供析构函数。或者,空的也可以同样有效。

另一方面,如果构造函数分配了一些资源(例如,连接到数据库),那么通常需要在析构函数中放入一些代码来释放该资源(例如,与数据库断开连接)。这是用于防止资源泄漏的standard C++ idiom

答案 5 :(得分:0)

像这样的类不需要一个非平凡的析构函数(一个带有“大括号之间的东西”)。

在析构函数中,您必须释放资源,您已“手动”分配。例如:

  • 如果你在构造函数中有new/new[]并且你需要在析构函数中释放这个内存
  • 如果您在构造函数中打开了一个文件,请在析构函数中将其关闭
  • 如果您在构造函数中锁定了互斥锁,请在析构函数中解锁它

这样的事情。

此外,当对象被破坏时,您可能需要实现一些额外的逻辑。取决于你想要做什么。

答案 6 :(得分:0)

据我所知或者担心,析构函数的定义应该总是这样:

~msgInfo() { /* free stuff */ }

另一方面,构造函数可能如下所示:

msgInfo(): m_var1(0), m_var2("Initialize") { /* further initialization */ }

:{之间的内容是成员变量初始化。

在析构函数中,你应该解除分配在类中其他地方动态分配的任何内容,因此:表示法并不好,因为你可能需要在对象上做delete

答案 7 :(得分:0)

在您的代码中,您可能没有任何动态内存分配,因此您不需要提供析构函数。