这是一个老问题,但@Alexandre问“为什么有人想这样做?”,我想我可以提供一个示例用法,我今天下午正在考虑。
遗留代码。使用裸指针Obj* Obj,并在末尾使用delete Obj。
不幸的是,我有时需要,而不是经常,让对象活得更久。
我正在考虑使它成为一个引用计数智能指针。但会有很多代码要改变,如果我是使用ref_cnt_ptr<Obj>无处不在。如果你混合裸Obj*和ref_cnt_ptr,当最后一个ref_cnt_ptr消失时,你可以隐式删除对象,即使Obj*仍然存在。
因此,我正在考虑创建一个explicit_delete_ref_cnt_ptr。例如,一个引用计数指针,其中删除只在显式删除例程中完成。在现有代码知道对象的生命周期的地方使用它,以及在我的新代码中使用它,使对象的生存时间更长。
在操作explicit_delete_ref_cnt_ptr时增加或减少引用计数。
但当在explicit_delete_ref_cnt_ptr析构函数中看到引用计数为零时,则不释放。
仅当在显式删除类操作中看到引用计数为零时才释放。例如:
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if( this->ptr ) {
this->rc--;
if( this->rc == 0 ) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
好吧,就像这样。引用计数指针类型不会自动删除rc'ed ptr析构函数中所指向的对象,这有点不寻常。但这似乎可以使混合裸指针和rc'ed指针更安全一些。
但到目前为止还不需要删除这个。
但后来我想到:如果被指向的对象,被指针,知道它被引用计数,例如,如果计数在对象内部(或在其他一些表中),那么例程delete_if_rc0可能是被指针对象的一个方法,而不是(智能)指针。
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if( this->rc == 0 ) {
delete this;
}
}
}
};
实际上,它根本不需要是一个成员方法,但可以是一个自由函数:
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if( keepalive_map[tptr] == 1 ) {
delete ptr;
}
};
(顺便说一句,我知道代码不太正确-如果我添加所有的细节,它变得不那么可读,所以我就这样留下它。)