我什么时候应该在C ++中使用自己的销毁功能?

时间:2014-02-20 13:54:53

标签: c++

最近我正在使用C ++学习OOP,在以下情况下我应该使用自己的销毁功能时我很困惑:

class T1{
private:
    int data;

public:
    T1(){...};
    ~T1(){}; // should I write my own function here?
};

class T2{
private:
    T1* pointer_to_T1;

public:
    T2(){...};
    ~T2(){}; // should I write my own function here?
};

class Node{
public:
    int data;
    Node* next;
};

class T3{
private:
    int size;
    Node* head;
public:
    T3(size){
        head = new Node[size];
    }
    ~T3(){}; // should I write my own function here?
};

我的计划中有三条评论可以澄清我的问题。我希望你能解释一下,如果你能给我一个一般规则,我将不胜感激。

7 个答案:

答案 0 :(得分:1)

如果class T3正在分配新内存,那么您必须在destructure中删除已分配的内存段。

class T3{
private:
    int size;
    Node* head;
public:
    T3(size){
        head = new Node[size];
    }
    ~T3(){
         delete[] head;
      }; 
};

答案 1 :(得分:0)

类的析构函数应该执行删除对象时所需的所有操作。

例如,它需要释放由类动态分配的所有内存。

答案 2 :(得分:0)

当您的类是基类时,您应该编写析构函数,并且您希望在对象被销毁时运行多态破坏。

如果对象拥有并管理资源,您可能需要一个构造函数。不要忘记复制和赋值操作符。

答案 3 :(得分:0)

对象应该自行清理。

IE,如果您在对象中分配内存,可能在构造函数中完成,那么您应该在析构函数中释放该内存。

析构函数用于在对象之后进行清理。所以你也可以做任何事情来帮助你做到这一点。

答案 4 :(得分:0)

类T1不需要明确定义析构函数。将编译器隐式定义析构函数就足够了。

类T2需要显式定义析构函数,以释放其具有类型指针的数据成员。否则会有内存泄漏。

类节点不需要显式定义析构函数。 T3类必须删除Node类的所有指针,因为它控制着节点的分配和释放。

答案 5 :(得分:0)

你需要声明一个析构函数:

  • 如果类管理需要在销毁时手动释放的资源;
  • 如果它打算是一个多态基类,在这种情况下它需要一个虚拟析构函数来允许多态删除。

在第一种情况下,您还需要提供或删除复制构造函数和复制赋值运算符;否则你最终可能会遇到两个或多个试图管理相同资源的对象。这被称为"Rule of Three"。通常,您可以使用现成的类(如容器和智能指针)来为您管理内存;因此,通常不需要自己使用析构函数。有人将此称为“零度规则”。

在第二种情况下,析构函数不必做任何事情(假设类没有尝试管理任何资源),它只需要是虚拟的。

针对您的具体示例:

  • T1不需要析构函数
  • T2可能,取决于它是否应该管理指针指向的任何内容。如果是,则考虑用智能指针替换指针,如std::unique_ptr<T1>
  • T3可能会这样做,因为它似乎在管理动态数组。你还需要考虑三法则;或者考虑使用std::vector<Node>自动管理阵列。

答案 6 :(得分:0)

我会尝试以一般方式回答您的代码段不具体。

通常会出现两种常见情况,您需要使用非平凡的析构函数。这不是一个完整的列表;只是最常见的情况。

1)在(多态)层次结构中。如果您的类是一个基类,意图从中派生,那么您的基类很可能具有非平凡的析构函数。而且,析构函数可能应该是virtual。这使得可以通过基类指针删除派生类对象,如下所示:

class Foo
{
public:
  virtual ~Foo(){}
};

class Bar : public Foo
{
};

int main()
{
  Foo* obj = new Bar;
  delete obj;
}

如果没有virtual析构函数,此程序将显示未定义的行为。

2)当你的班级成员需要的不仅仅是琐碎的破坏。一个简单的例子就是你的类有一个成员,它是一个原始指针(如不是智能指针),是使用new。该指针需要delete d,析构函数可能是正确的位置。如果您的类具有复制构造函数或复制赋值运算符(operator=),则表明您的类管理非平凡可破坏成员的良好迹象。如果你的类有任何一个,那么它可能需要它们 plus 一个析构函数来处理分配的内容。 (参见Rule of Three)这不是唯一的指示 - 你可能只有一个默认的构造函数,但仍然需要一个析构函数。这取决于你班级的作用。

相关问题