Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “有什么用?”;删除此“;?_C++_Memory Management_Destructor_Self Destruction - Fatal编程技术网

C++ “有什么用?”;删除此“;?

C++ “有什么用?”;删除此“;?,c++,memory-management,destructor,self-destruction,C++,Memory Management,Destructor,Self Destruction,今天,我看到了一些遗留代码。在析构函数中有一个类似“删除此””的语句。我想,这个调用将是递归的。它为什么起作用 我在Y上快速搜索了一下!,我发现,如果需要限制用户创建堆栈对象,我们可以将析构函数设置为私有,并提供一个删除实例的接口。在提供的接口中,我们必须对该指针调用delete 使用此类语句还有其他情况吗?“删除此项”通常用于ref计数的对象。对于ref计数对象,何时删除的决定通常放在对象本身上。下面是一个发布方法的示例[1] int MyRefCountedObject::Release()

今天,我看到了一些遗留代码。在析构函数中有一个类似“
删除此”
”的语句。我想,这个调用将是递归的。它为什么起作用

我在Y上快速搜索了一下!,我发现,如果需要限制用户创建堆栈对象,我们可以将析构函数设置为私有,并提供一个删除实例的接口。在提供的接口中,我们必须对该指针调用delete

使用此类语句还有其他情况吗?

“删除此项”通常用于ref计数的对象。对于ref计数对象,何时删除的决定通常放在对象本身上。下面是一个发布方法的示例[1]

int MyRefCountedObject::Release() {
  _refCount--;
  if ( 0 == _refCount ) {
    delete this;
    return 0;
  }
  return _refCount;
}
ATL COM对象就是这种模式的主要示例


[1] 是的,我知道这不是线程安全的。

删除此在析构函数中无效。它可以在其他地方使用。但这很少是个好主意。
wxWidgets
框架将其用于线程类。它有一种模式,当线程结束执行时,它会自动释放系统资源和自身(wxThread对象)。我觉得它很烦人,因为从外部看,你不知道引用它是否有效——你不能再调用像
IsValid
这样的函数了,因为对象不存在。这听起来像是
删除此
的主要问题,除了它不能用于非动态对象之外

如果这样做,请确保不要触摸任何数据成员,也不要再对以这种方式删除的对象调用任何成员函数。最好将其作为非虚拟、受保护或私有函数中的最后一条语句。调用delete在虚拟和/或公共函数中也是有效的,但我会限制执行该操作的方法的可见性

政府对此有一条记录。C++标准引用我的上述要求(<代码> 3.8p5< /代码>):

在对象的生存期开始之前,但在分配对象将占用的存储之后,或者在对象的生存期结束之后,在重用或释放对象占用的存储之前,任何指向对象将要或曾经所在的存储位置的指针都可以使用,但只能以有限的方式使用。[…]如果对象将是或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,则程序具有未定义的行为


生命周期在对象的析构函数开始执行时结束。请注意,对于正在构建和销毁的对象(例如,允许访问非静态数据成员),在段落之后出现的规则有例外,详见<代码> 12.7代码> > < /p> 。在C++的早期,认为这是很好的理由。例如,引用计数对象的自删除(正如JaredPar所说)。
据我所知,从长远来看,它们都是一个坏主意。

在双链接列表中,可以删除节点而不引用任何外部结构,例如高级“列表”对象。这使得每个节点处理自己的释放(可能与一个互补的静态方法结合处理来自同一内存池的初始分配)是合理的。在这种情况下,节点对象删除自身(当用户请求时)是有意义的


尽管如此,在不释放任何内存的情况下,将节点从一个列表中取消链接并链接到另一个列表也是合理的,因此不希望单个删除操作无条件释放内存。

而自删除参照计数对象是一种非常常见的模式,我认为最初的问题是把它放在析构函数中,而不是放在Release()函数中,在这种情况下,它简直是疯了。@rmeador,实际上有两个问题。标题和最后一句都表明,我们想知道“删除此项;”的有效用法。我希望我能回答这个问题。中间部分确实提出了一个问题:“为什么要在dtor中删除此项?”。我同意这样做似乎有点疯狂。您的示例代码有一个bug。如果_refCount是一个成员变量,那么当您“删除此”时,该成员变量将不再存在,因此您的“return _refCount”行具有未定义的行为。这正是我的想法。今天,如果我需要编写一个ref counted对象,我会将数据保存在一个额外的对象中,并在reference count降至零时使宿主对象(复制的对象)删除包装的数据。自我删除气味:)@johannesschaub-litb:完全同意;负责其职责并决定何时清理自身的对象?恶心@Johanneschaub litb然后主机对象必须在完成时自行删除。。。
void RemoveAndDeallocate()
{
    LinkedListNode *current_prev = prev, *current_next = next;
    current_prev->next = current_next;
    current_next->prev = current_prev;
    delete this;
}