C++ 删除这个?它有什么作用?

C++ 删除这个?它有什么作用?,c++,destructor,delete-operator,self-destruction,C++,Destructor,Delete Operator,Self Destruction,鉴于以下情况: #include <iostream> using namespace std; class A { public: void func() {delete this;} A() : x(5) {cout << "ctor A" << endl;} ~A() {cout << "dtor A" << endl;} int x; }; int main() { A a;

鉴于以下情况:

#include <iostream>
using namespace std;

class A
{
public:
    void func() {delete this;}
    A() : x(5) {cout << "ctor A" << endl;}
    ~A() {cout << "dtor A" << endl;}
    int x;
};

int main() {
    A a;
    cout << "The X value: " << a.x << endl;
    a.func();  // calling 'delete this' ->going to the dtor #1
    cout << "The X value: " << a.x << endl;
    return 0;  
}

是否
删除此项有什么严重的影响吗

你不应该这样做。这是糟糕的编程实践。使用new的对象应该是使用delete的对象。否则您会陷入混乱,最终导致内存泄漏等。

在这种情况下(您没有通过new分配对象),您正在调用未定义的行为。未定义的行为通常是非常非常糟糕的事情。基本上,任何事情都可能发生


不过,也可以在“deletetthis;”可以的地方编写代码。但我记不起曾经这样做过。尽量避免。通过将此职责委托给其他对象(例如,智能指针),尝试避免完全手动调用delete(无论您是否使用new)。

我将查看您在堆栈分配对象上调用的
delete
,并检查
delete this
的一般用法

有一个学派认为“这不是一个好主意”。但是,我已经看到它多次用于引用计数对象的实现

在中,框架要求所有对象都由工厂方法创建,然后通过调用“Release”再次释放

注意-这不是一个完整的实现,只是给出了一个逻辑概念。
但是,通过将构造函数设置为私有,我可以确保它只能在堆上分配。

delete
操作符调用对象的析构函数,然后释放对象使用的底层内存。内存必须已由
new
操作员分配。在
删除此
中,删除的对象只是当前对象。结构没有什么特别的,只是普通的C++。 在您的示例中,内存来自堆栈,因此您将进入未定义行为的领域(因为您正在对未通过
new
操作符分配的对象调用
delete
操作符)

调用
删除此
通常被认为是糟糕的设计,因为对象不应该对其自身的生命周期负责。一般认为最好的做法是让物体的创造者对其破坏负责

然而,有一种情况我个人认为它非常有用。当线程通过发送消息进行通信时,就会发生这种情况。在这种情况下,如果消息负责它自己的生命周期,那么它实际上比由原始线程负责更安全、更容易编写。


这就是说,在正确组织的代码中,您几乎不应该使用它。

尝试删除未通过new:Error分配的内容。试图在删除后访问某个对象:错误。我同意你的看法,我想表明的是,即使在第一次删除调用之后,该对象仍然保留“x”的值。。。我觉得有点奇怪,“x”值可能是5,也可能不是。应用程序可能会崩溃,也可能不会崩溃。看看这个经典的解释:我很好奇:是什么促使你尝试这个?我也很好奇。我知道这是一个禁忌!只是想知道为什么,明白了。那么为什么在第一次删除调用之后,“a.x”仍然保留值“5”?为什么程序没有崩溃?好吧,当您达到未定义的行为时,任何事情都可能发生,即使程序按照您预期的方式工作。由于您没有析构函数,因此该值没有更改,并且由于对象位于堆栈上,因此仍然可以访问该对象。但是,您可能损坏了分配器。但是没有任何保证,这是UB的根源。对象什么都不做。它们只是存在而已。函数做事情。
ctor A
The X value: 5
dtor A
The X value: 5
dtor A
  class MyRefCountedObject : public IUnknown
  {
      private:
           // Making the constructor and destructor private
           // so that the object can only be allocated as a pointer

           MyRefCountedObject() {}

           ~MyRefCountedObject() {}

           MyRefCountedObject(const MyRefCountedObject& mrco) {}

            int _refCount;
      public:
           static MyRefCountedObject* CreateInstance()
           {
                MyRefCountedObject* pObject = new MyRefCountedObject();
                pObject->_refCount = 1;
                return pObject;
           }

           void Release()
           {
                if(--_refCount == 0)
                {
                    delete this;
                }
           };
           void AddRef()
           {
               ++_refCount;
           }
  }