具体来说,在库中,我有一个内存池,它覆盖了某些类的new和delete的行为。我希望库的用户能够在这些类的实例上调用delete,但是我需要保持实例处于活动状态,直到稍后进行特定的清理操作。让用户使用常规新/删除时,这是否可行?有些方法可以覆盖调用析构函数的默认行为吗?
答案 0 :(得分:4)
使用智能指针而不是new
/ delete
(这无论如何都是好的做法)。
使用自定义删除程序将对象的所有权移至“等待清理”对象列表。
有关智能指针的示例,请参阅std::unique_ptr
和std::shared_ptr
。
另一个选项(更加努力,更难以实现)只是将对象存储在使用自定义分配器的容器中,并让分配器的destroy
和deallocate
函数执行“移动到一个用于清理的临时区域而不是实际销毁它“部分。我建议使用自定义删除方法的智能指针,而不是分配器方法。
这两个选项(自定义删除器和自定义分配器)允许您控制对象被“销毁”时的确切行为,将对象生命周期的实际结束与用户处理它的时刻分开,这是无法完成的delete
运营商。
答案 1 :(得分:4)
简答:不。
调用delete
始终会触发对析构函数的调用,之后调用operator delete
,与调用new
的方式相同,首先调用相应的{{1}然后运行该对象的构造函数。
如果你想阻止你的用户破坏对象你必须以某种方式阻止他们a)在原始指针上调用delete并且b)在堆栈上构造它们。
如果你想保持实例存活,听起来像你想要管理它们的生命周期,所以自然的方式就是首先在你的库中创建对象。此外,无论如何,在代码中使用普通operator new
调用被认为是糟糕的风格,因为有可用的智能指针自动执行这些调用。
所以你可以做的是在你的库中添加创建者函数,返回某种智能指针。这些可以是delete
或shared_ptr
s,带有一个特殊的删除器,它不会真正删除该对象,而是将其传递回您的库以便稍后清理。
答案 2 :(得分:2)
delete
运行析构函数。这是每个人都依赖的基本事实。如果你能以某种方式禁用析构函数调用,你不能这样做,那么你就会打破每个人的期望。如果您不希望用户调用析构函数,请不要让析构函数可用。受保护的析构函数会使delete
不可调用。