2014-01-13 64 views
0

任何人都可以告诉我,如果我忘记在C++类中声明一个destrucor,对象的内存会发生什么?我的意思是,它是否被释放或导致内存泄漏? 一个例子或演示将不胜感激。缺少析构函数声明

在此先感谢。

+0

这取决于你的班级。举例说明。 – user1810087

回答

3

定义任何非平凡类的析构函数通常被认为是一种好的做法(请参阅Rule of Three)。然而,在现代C++(即C++ 11以后)中,它不像以前那样必要。

如果您的类不是从其他任何东西继承的,则任何直接成员(如变量和对象)都将被编译器提供的缺省析构函数正确销毁。同样,如果你的对象拥有任何堆分配的对象,这些对象被包装在智能指针中,它们也将被安全销毁。

如果您的对象拥有通过原始指针分配的任何堆数据,则会出现问题。隐含的析构函数无法知道如何处理它们,所以你需要一个自定义的析构函数来清除它们。例如:

class MyClass 
{ 
    int m_data1; 
    std::string m_data2; 
    std::shared_ptr<Widget> m_data3; 
    Widget *m_data4; 
}; 

在上述例子中,成员m_data1m_data2,并m_data3都将没有一个自定义的析构函数正确地清除行动。但是,m_data4指向的对象将自动清除而不是。如果它是由MyClass分配的,那么它通常会导致内存泄漏(除非它被其他东西释放)。

所有这一切都表明,继承以一种重要的方式改变了事物。如果你的课程由其他任何东西继承,那么你应该总是给它一个虚拟析构函数。如果您的对象通过指向继承类的指针被删除,并且该类不具有而不是具有虚拟析构函数,那么子类的析构函数将永远不会被调用,从而可能导致内存泄漏。

例如:

class Parent 
{ 
public: 
    Widget m_data1; 
} 

class Child : public Parent 
{ 
public: 
    Widget m_data2; 
} 

int main() 
{ 
    Parent *ptr = new Child; 
    delete ptr; // <-- clears-up Parent but not Child 
} 

在上述例子中,是ptr类型Parent,所以delete只知道对象的Parent一部分。这意味着只有m_data1才能正确清除。没有虚拟析构函数,它不知道对象的Child部分,所以m_data2将不会被正确地清除(它的析构函数将永远不会被调用)。

2

如果未声明析构函数,编译器将生成析构函数,该函数将调用对象的所有成员的析构函数。只有在使用原始内存(C文件,内存分配等)时才可能泄漏。

2

这取决于班级的数据成员。如果类管理资源,那么它需要一个析构函数来释放它们(你还应该提供一个拷贝构造函数和赋值操作符,或者使该类不可复制和不可赋值)。

如果该类有内置数据成员或管理自己资源的数据成员,那么隐式生成的析构函数就足够了。它将调用所有数据成员的析构函数。