这是一个旧问题,已经有答案了,但@Alexandre问道“为什么有人想这么做?”,我想提供一个我今天下午考虑的用例。
遗留代码。使用裸指针Obj* obj,并在末尾使用delete obj。
不幸的是,有时我需要让对象保持更长时间的生命。
我正在考虑将其制作成引用计数智能指针。但是,如果我要在所有地方都使用ref_cnt_ptr ,那么需要改变的代码将非常多。而且如果你混合使用裸的Obj*和ref_cnt_ptr,即使还有Obj*存在,当最后一个ref_cnt_ptr消失时,对象也可能被隐式删除。
因此,我考虑创建一个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;
}
}
};
好的,类似这样。如果一个引用计数指针类型在其析构函数中不自动删除指向的对象,这有点不寻常。但这似乎可以使裸指针和引用计数指针混合使用更加安全。
但到目前为止,还没有需要使用delete this的情况。
但是,随后我想到:如果所指向的对象知道它正在被引用计数,例如计数在对象内部(或其他表格中),则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;
}
};
(顺便说一句,我知道代码不太对——如果我添加所有细节,它会变得不那么易读,所以我就像这样保留了它。)
setWorkingModule
中删除吗? - Jimmy T.PostNcDestroy
中执行delete this;
,因为这时候它所包装的WinAPI类被销毁了。因此,我认为它确实有自己有效的用例。 - Ayxan Haqverdili