什么时候需要声明自己的析构函数?


class Point    
{
public:
    float x,y;
    Point() {}
    Point(float,float);
    Point operator + (Point);
    Point operator * (double);
    void rotate_p(float);
    void render_p(Point*);
    void sub(float);
    float get_dist();//get_distance
};
正如你所看到的,这个类没有指针作为非静态数据成员,所以我认为我可以使用默认析构函数;这准确吗?

问题
    什么时候我需要声明自己的析构函数?

介绍

由于具有自动存储持续时间的数据成员的生命周期与拥有它们的实例的生命周期绑定在一起,因此不需要显式调用它们的析构函数;当类的实例存在时,它们总是被销毁。


通常什么时候需要声明自己的析构函数?

通常必须显式地声明自己的析构函数:

  • 你正在声明一个类,它应该作为涉及多态性的继承的基,如果你这样做,你将需要一个虚拟析构函数来确保在通过指向的指针/引用销毁派生类时调用该析构函数。

  • 您需要释放类在其left time期间获得的资源

    • 示例1:类有一个文件句柄,当对象销毁时需要关闭;

    • 示例2:类拥有一个具有动态存储持续时间的对象,因为对象的生命周期可能在类实例被销毁后很长时间内仍然存在,因此需要在析构函数中显式地销毁它。


隐式生成的析构函数

除非你显式地声明你自己的析构函数,否则编译器会为你创建一个隐式生成的析构函数。

14.4p4 析构函数 [class.dtor]

如果类没有用户声明的析构函数,则有析构函数隐式声明为默认值(8.4)。隐式声明的析构函数是其类的内联公共成员。

<一口> src: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf


然而,在一些罕见/高级的情况下,编译器会拒绝为你生成析构函数,在这些情况下,你必须显式地声明你自己的析构函数,或者确保你的类实例的析构函数永远不会被调用;因为要析构对象,必须使用析构函数。

14.4p5 析构函数 [class.dtor]

类X的默认析构函数定义为delete,如果:

  • X是一个类并,它有一个非平凡的变体成员析构函数,

  • 任何非静态数据成员都具有类类型M(或数组)其)和M具有删除的析构函数或析构函数为从默认析构函数

  • 中不可访问
  • 任何直接基类或虚基类都有删除的析构函数或从默认析构函数

  • 中无法访问的析构函数
  • ,或者,对于虚析构函数,查找非数组的释放函数会导致歧义或导致被删除的函数

<一口> src: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf


可在以下链接阅读更多内容:

  • cppreference.com -析构函数

析构函数的主要目的是从堆中释放已使用的内存或删除指向其他对象的链接等。这里不需要从堆中分配内存,不需要在对象之间建立任何关系,因此不需要析构函数。

你可能还想看看"三法则"三法则(也称为三巨头法则或三巨头法则)是c++中的一条经验法则,它声称如果一个类定义了以下其中一个,它可能应该显式地定义所有三个:

析构函数,拷贝构造函数,复制赋值运算符,维基百科链接:http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

如果在编译时占用内存(即在运行时不分配内存),则可以创建析构函数,但这不是必需的。在这种情况下,类的析构函数隐含在类的定义中;在后台将为您提供析构函数,当类的实例超出作用域时,将释放内存。

编辑:一个简单,方便的教程可以在这里找到- http://www.learncpp.com/cpp-tutorial/86-destructors/

  • 如果你没有定义析构函数,语言会为你定义一个析构函数。

  • 一般来说,将析构函数定义为virtual是一个好主意,以确保如果有人继承了你的类,事情将是正常的。

  • 但是,如果您在构造函数中动态分配内存,则必须定义析构函数,并确保在其中删除任何分配的内存,以避免内存泄漏。

  • 另一个建议是,如果你的编译器支持c++ 11特性,最好避免使用原始指针来分配内存,而使用智能指针(即RAII)。因此,您不必在析构函数中删除任何先前分配的内存。

析构函数是在对象被销毁时执行的代码…时期。

析构函数中的内容取决于与对象相关的语义。

在析构函数中(但也可能在其他地方,例如,考虑一个池化对象)的典型内容

  1. 释放对象当前拥有的所有内存(注意,它可能已经分配了内存,但转移了其所有权)。
  2. 释放对象已获取的所有资源。

例外是必须声明析构函数,即使在类的层次结构中为空,也需要能够从指向父类的指针销毁子类的对象。

如果你没有定义一个默认析构函数,编译器将为你提供一个默认的析构函数。此外,类中包含的属性将在(隐式/显式)类析构函数运行后自动调用其析构函数。

最新更新