C++中需删除指向同内存的多指针吗?Wrapper类析构疑问
C++包装类内存管理疑问解答
外部库代码
class Subfeature { }; class BigFeature { Subfeature* subfeature; // more properties/methods ... public: Subfeature* get_subfeature(); BigFeature(); ~BigFeature(); // In this destructor, subfeature is deleted };
该库代码混乱但规模过大无法修改,因此编写了如下Wrapper类:
class BigFeatureWrapper { class SubfeatureWrapper { Subfeature* subfeature; // more properties/methods etc. public: // This constructor calls get_subfeature method in BigFeature and set it in subfeature property SubfeatureWrapper(BigFeature* bigfeature) { this->subfeature = bigfeature->get_subfeature(); }; }; SubfeatureWrapper* subfeaturewrapper; BigFeature* bigfeature; public: BigFeatureWrapper() { this->bigfeature = new BigFeature(); this->subfeaturewrapper = new SubfeatureWrapper(this->bigfeature); } ~BigFeatureWrapper() { delete this->bigfeature; // Should I define destructor for SubfeatureWrapper // and write `delete this->subfeaturewrapper;` here? } };
疑问
- 是否需要为SubfeatureWrapper定义析构函数,并在BigFeatureWrapper的析构中执行
delete this->subfeaturewrapper;以避免内存泄漏或未定义行为? - 由于BigFeature的析构函数会删除subfeature指针,SubfeatureWrapper中的Subfeature*是否属于冗余?
解答
问题1:关于析构函数与delete subfeaturewrapper
- 必须在BigFeatureWrapper的析构中执行
delete this->subfeaturewrapper;:subfeaturewrapper是通过new创建的堆对象,若不手动delete,这块堆内存永远无法被回收,会造成内存泄漏。 - 不需要为SubfeatureWrapper自定义析构函数:SubfeatureWrapper里的
subfeature指针由BigFeature负责生命周期管理(BigFeature的析构会主动删除它),SubfeatureWrapper只是持有指针的引用,不能也不需要去delete这个指针——否则会触发双重释放的未定义行为。编译器默认生成的析构函数就足够,它只会释放SubfeatureWrapper自身的内存,不会触碰subfeature指针。
注意:当前代码先delete bigfeature再delete subfeaturewrapper的顺序是安全的,因为删除subfeaturewrapper时仅销毁wrapper对象本身,不会访问已经失效的subfeature指针(只要SubfeatureWrapper的析构和其他方法不在此时操作该指针)。
问题2:SubfeatureWrapper中的Subfeature*是否冗余
这取决于SubfeatureWrapper的实际用途:
- 如果SubfeatureWrapper只是单纯存储指针,没有任何封装逻辑(比如简化Subfeature的接口、添加参数校验等),那这个指针确实冗余,直接在BigFeatureWrapper里调用
bigfeature->get_subfeature()就能拿到目标指针。 - 如果SubfeatureWrapper是用来封装Subfeature的操作(比如把复杂调用简化、添加错误处理),那这个指针是必要的——它是Wrapper类访问底层Subfeature对象的入口。
另外需要注意:BigFeature销毁后,SubfeatureWrapper里的subfeature会变成悬空指针,必须保证SubfeatureWrapper的生命周期不超过BigFeature。当前代码的销毁顺序(先删BigFeature,再删SubfeatureWrapper)是安全的,只要SubfeatureWrapper在销毁时不访问这个悬空指针就不会出问题。
内容的提问来源于stack exchange,提问作者user22251471
相关产品推荐
相关产品推荐

