为何Win32 COM示例中类采用公有构造函数+私有析构函数?
问题
我正在研究微软官方的异步回调示例,其中的回调类SourceReaderCB拥有公有构造函数:
public: SourceReaderCB(HANDLE hEvent) : m_nRefCount(1), m_hEvent(hEvent), m_bEOS(FALSE), m_hrStatus(S_OK) { InitializeCriticalSection(&m_critsec); }
但析构函数为私有:
private: // Destructor is private. Caller should call Release. virtual ~SourceReaderCB() { }
示例中使用new创建对象:
// Create an instance of the callback object. pCallback = new (std::nothrow) SourceReaderCB(hEvent); if (pCallback == NULL) { hr = E_OUTOFMEMORY; goto done; }
该对象似乎内部采用智能指针逻辑,但外部使用裸指针。若不主动delete该指针,是否会造成内存泄漏?
回答
- 这个类采用的是COM标准的引用计数生命周期管理模式:构造函数里初始化
m_nRefCount(1),说明它必然实现了AddRef()和Release()方法(这是COM接口的核心方法)。 - 私有析构函数的设计就是为了禁止外部直接调用
delete,对象的销毁只能由类内部的Release()方法触发:当Release()把引用计数减到0时,会调用delete this来销毁对象,此时私有析构函数可以被类内部代码正常调用。 - 不需要手动调用
delete,反而手动delete会直接报错(因为析构是私有,外部无法访问),而且违背引用计数的管理逻辑。 - 会不会内存泄漏的关键在于是否正确管理引用计数:只要你(或者使用该回调的
SourceReader组件)在不再需要对象时调用Release(),引用计数归0后对象会自动销毁,不会泄漏;但如果完全不调用Release(),引用计数一直大于0,对象永远不会被销毁,就会造成内存泄漏。
内容的提问来源于stack exchange,提问作者G B
相关产品推荐
相关产品推荐

