【问题标题】:Does the destructor get called automatically析构函数是否被自动调用
【发布时间】:2012-03-18 06:11:47
【问题描述】:

我的问题很简单,但我无法在任何地方找到问题。

如果我有这样的课程

class A {
    vector<int> data;
}

A 的实例被销毁时,data 也会被正确销毁,还是我应该为A 编写一个调用data 的析构函数的析构函数?基本上我担心当A 的实例被销毁时,vector 的动态内存是否不会被释放。我怀疑答案是 data 已正确释放,但我不想发现我错了。

此外,如果A 是一个结构,当A 的本地实例超出范围时,data 的析构函数会被调用吗?

【问题讨论】:

  • class A 的声明后缺少分号(这不是真正的声明,因为它缺少......哦,好吧)。

标签: c++ destructor


【解决方案1】:

是的,data 会被自动销毁,你不需要做任何事情来实现它。 vector 将处理由它分配的动态内存的清理。当A 的实例被销毁时,将自动调用向量的析构函数。

无论Aclass 还是struct,行为都没有区别。

【讨论】:

  • +1 为了清楚起见,“vector 将处理 它分配的动态内存的清理”,而不是 to 它。如果您将动态分配的对象存储在向量中,则您有责任相应地delete 它们。
  • @netcoder 发现您的评论有点误导。您可以将 指向动态分配对象的指针 存储在向量中,但我认为您不能存储在向量中动态分配的“对象”本身。如果您声明一个vector,其中ClassA 是一个类名,那么vector 将负责销毁它所拥有的ClassA 对象。当然,如果你的 ClassA 对象持有指向其他对象的指针,那么删除它们是 ClassA 的责任不是 vector 的责任,但那是另一回事了。
【解决方案2】:

不需要,数据成员的析构函数总是被调用。

显式析构函数是有用的手动内存管理

struct a{
    int* ip;
    a() 
    : ip(new int(5)) 
    { }

    ~a() { delete ip; }
};

也就是说,一般来说,您应该使用 RAII 容器(例如智能指针),所以我个人很少在那里写 dtors。

例外情况是将基类 dtor 声明为虚拟。

struct base {
     virtual ~base() {}
};
struct child : public base {
    //base and child destructor automatically called 
}

【讨论】:

  • +1 坚持良好的 RAII 原则。当人们按照 Stroustrup、Sutter、Meyers 和其他现代 C++ 思想家希望我们编写 C++ 的方式编写 C++ 时,手动编写析构函数的需求应该会越来越少。
【解决方案3】:

如果你自己没有定义一个默认析构函数,编译器会自动创建一个。通常,您不需要创建自己的析构函数,除非您拥有“拥有”它们指向的内存的指针数据成员,和/或您正在设计您的类以由其他类派生,此时您想要至少声明一个空的virtual 析构函数。

在所有情况下,无论是使用您自己的析构函数,还是编译器创建的默认析构函数,所有非静态数据成员的析构函数以及当前类的任何基类都会在结束时调用析构函数和析构函数本身返回之前。

【讨论】:

    猜你喜欢
    • 2017-02-27
    • 2013-06-25
    • 1970-01-01
    • 2012-01-12
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多