缺少析构函数声明
回答
定义任何非平凡类的析构函数通常被认为是一种好的做法(请参阅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_data1
,m_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
将不会被正确地清除(它的析构函数将永远不会被调用)。
如果未声明析构函数,编译器将生成析构函数,该函数将调用对象的所有成员的析构函数。只有在使用原始内存(C文件,内存分配等)时才可能泄漏。
这取决于班级的数据成员。如果类管理资源,那么它需要一个析构函数来释放它们(你还应该提供一个拷贝构造函数和赋值操作符,或者使该类不可复制和不可赋值)。
如果该类有内置数据成员或管理自己资源的数据成员,那么隐式生成的析构函数就足够了。它将调用所有数据成员的析构函数。
- 1. C++:“错误C4430:缺少类型说明符 - 假定INT”对于构造和无效的声明析构函数
- 2. 向前声明和析构函数
- 3. 向前声明和析构函数
- 4. C++前向声明和析构函数
- 5. 缺少声明标识符
- 6. 缺少退货声明?
- 7. dom4j HTMLWriter缺少XML声明
- 8. 缺少包声明:'com.VRCoreSoftware.testapp4'
- 9. 缺少方法声明
- 10. DialogPreference缺少构造函数
- 11. 解析函数声明Javascript
- 12. LCOV:分支机构的析构函数缺少
- 13. “{”缺少函数头(旧式格式列表) - 预期声明
- 14. C为什么容忍缺少函数声明?
- 15. C#构造函数声明
- 16. 语法错误:缺少;声明
- 17. 缺少jQuery插件;声明(jQuery的)
- 18. SQL错误声明,缺少操作员
- 19. WebStorm 2016.3.2“缺少导入声明”
- 20. 声明log4net后缺少程序集ILog
- 21. 缺少方法声明的上下文
- 22. Office 365统一API - 缺少UPN声明
- 23. waitForCondition缺少;之前声明错误
- 24. Python,TypeError:缺少位置声明
- 25. 错误:“缺少;声明之前”
- 26. 语法错误:缺少;在正常声明之前的声明
- 27. 析构函数删除主动声明的动态数组
- 28. 缺少构造函数初始化
- 29. 缺少'()'调用构造函数
- 30. 在类的析构函数中声明refrences /对象
这取决于你的班级。举例说明。 – user1810087