首页 > 解决方案 > 定义类 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() 继承的向量。

标签: c++oopc++11

解决方案


析构函数正确吗?我的代码有内存泄漏吗?

可能。如果X应该获取objectZ其数组中对象的所有权,则需要在释放数组本身之前释放这些对象,否则它们会被泄露。

在旁注中,您的main()示例正在泄漏x1对象。目前尚不清楚您是否打算调用delete x1而不是调用delete o1,或者是否x1->add(o1)应该拥有所有权o1

如何正确定义类 X 的析构函数而不会出现内存泄漏

首先不进行手动内存管理。正确使用智能指针std::unique_ptrstd::shared_ptr, 并让它们为您处理内存管理。

考虑到它也继承自指向另一个objectY的指针向量,我是否需要将向量1乘以1个元素循环并对其调用delete

很可能,是的。这实际上取决于所采用的所有权模式X。如果X拥有objectYobjectZ对象,则它负责释放它们。否则,如果它没有取得所有权,那么它不负责释放它们。

最后是 clear() 还是 clear() 足够了?

对于原始指针数组,clear()只需从数组中删除指针,它不会释放指向的对象。另一方面,智能指针数组将在智能指针从数组中删除时释放对象。

我的想法是,因为我没有从 X 类中分配内存,所以我也不需要释放它。

任何分配的对象new都必须用 释放delete。这是否需要在内部发生X将取决于X特定的所有权模型。


推荐阅读