c++ - 定义类 X 的析构函数,它继承自指向对象 Y 的指针向量并具有指向 Z 的指针数组
问题描述
所以我会尽量清楚这一点。假设我们有以下内容:
class X : protected vector<objectY*>
{
private:
objectZ** array;
unsigned size;
unsigned capacity;
public:
X():size(0), capacity(0), array(new objectZ*[100]){}
X(const objectX& o); // to be defined later
X& operator=(const X& x); //defined later
~X(){ delete [] array; clear(); } <--- is this correct, or it produces memory leak?
void add(objectZ* o); // used to add objects to array
}
现在假设我们已经使用编译上述代码所需的所有基本内容定义了类 Y 和 Z。我的问题如下:析构函数是否正确?我的代码有内存泄漏吗?
假设我去 main() 并这样做:
objectZ* o1 = new objectZ();
objectX* x1 = new objectX();
x1->add(o1);
delete o1; // to avoid memory leak;
return 0; // end of main.
因为我主要是从 main 向 objectX 的数组添加东西,并且很可能使用多态性,比如
objectZ* ok = new objectK(); // where k is derived from Z
x1->add(ok);
如何在没有内存泄漏的情况下正确定义类 X 的析构函数,并且考虑到它还继承自指向另一个 objectY 的指针向量,我是否需要将向量 1 乘以 1 元素循环并对其调用 delete 和 clear()最后还是 clear() 足够了?我是否也循环数组并对其元素调用删除?我的想法是,因为我没有从 X 类中分配内存,所以我也不需要释放它。我只需要删除 [] 数组,可能还有 clear() 继承的向量。
解决方案
析构函数正确吗?我的代码有内存泄漏吗?
可能。如果X
应该获取objectZ
其数组中对象的所有权,则需要在释放数组本身之前释放这些对象,否则它们会被泄露。
在旁注中,您的main()
示例正在泄漏x1
对象。目前尚不清楚您是否打算调用delete x1
而不是调用delete o1
,或者是否x1->add(o1)
应该拥有所有权o1
。
如何正确定义类 X 的析构函数而不会出现内存泄漏
首先不进行手动内存管理。正确使用智能指针std::unique_ptr
和std::shared_ptr
, 并让它们为您处理内存管理。
考虑到它也继承自指向另一个objectY的指针向量,我是否需要将向量1乘以1个元素循环并对其调用delete
很可能,是的。这实际上取决于所采用的所有权模式X
。如果X
拥有objectY
和objectZ
对象,则它负责释放它们。否则,如果它没有取得所有权,那么它不负责释放它们。
最后是 clear() 还是 clear() 足够了?
对于原始指针数组,clear()
只需从数组中删除指针,它不会释放指向的对象。另一方面,智能指针数组将在智能指针从数组中删除时释放对象。
我的想法是,因为我没有从 X 类中分配内存,所以我也不需要释放它。
任何分配的对象new
都必须用 释放delete
。这是否需要在内部发生X
将取决于X
特定的所有权模型。
推荐阅读
- html - 嗨,我遇到了 facebook fanpage 插件没有出现的问题
- .net-core - 将 Websocket 负载平衡到多个容器中
- rust - 借用新对象实例时如何指定生命周期?
- dataweave - 将嵌套数组转换为与 mulesoft dataweave 中的父级相同的级别
- android - 如何制作一个适合父母大小的圆形盒子组成android
- java - Java:为什么我的代码在输入异常时会自动无限循环,而不是等待新的输入?
- web-scraping - 抓取具有表单并将响应提交为 html 表的网页
- amazon-sagemaker - 如何在 SageMaker 中进行 unrar 操作?
- svelte - SvelteKit 中应用程序特定的编译时间设置
- github - github如何在容器中克隆组织的私有存储库