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

时间:2014-06-11 16:07:36

标签: c++ class destructor

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
};

正如您所看到的,此类没有非静态 数据成员的指针,所以我想我可以使用默认的析构函数;这准确吗?


问题

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

6 个答案:

答案 0 :(得分:11)

简介

由于自动存储持续时间的数据成员的生命周期与具有它们的实例的生命周期绑定,因此您无需明确调用其析构函数;只要类的实例是,它们就会被销毁。


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

通常情况下,如果出现以下情况,则必须显式声明自己的析构函数:

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

  • 您需要在leftime期间释放该类获取的资源

    • 示例1 :该类具有文件句柄,需要在对象析构时关闭;析构函数是最理想的位置。

    • Exempel 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


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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

当在编译时考虑内存(即在运行时没有分配内存)时,可以创建析构函数,但这不是必需的。在这种情况下,班级的暗示者暗示了这个类的析构函数。定义;将在幕后为您提供析构函数,当类的实例超出范围时,将释放内存。

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

答案 3 :(得分:1)

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

  • 通常,将析构函数定义为virtual是一个好主意,以确保如果某人从您的班级继承,那么事情就会好起来。

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

  • 另一个建议是,如果您的编译器支持C ++ 11功能,那么最好避免内存分配的原始指针并使用智能指针(即RAII)。因此,您不必删除析构函数中以前分配的任何内存。

答案 4 :(得分:1)

析构函数是在对象被销毁时执行的代码...句点。

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

析构函数中的

典型的东西(但可能会去其他地方,例如想到一个池化对象)

  1. 释放对象当前拥有的所有内存(请注意,它可能已分配内存但已转让其所有权)。
  2. 释放对象获取的所有资源。
  3. ....
  4. 例外情况是你必须声明一个虚拟析构函数,即使在类的层次结构中为空时,你也需要能够从指向父类的指针中销毁子类的对象。

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

答案 5 :(得分:1)

您可能还想看看“三个规则” 三规则(也称为三巨头或三巨头的规则)是C ++中的经验法则,声称如果一个类定义了下面的一个,它应该明确地定义所有三个:

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