删除和析构函数(C ++)的一个有趣案例

删除和析构函数(C ++)的一个有趣案例

问题描述:

我有一段代码,可以多次调用析构函数,并访问成员函数,即使在保留成员变量值的情况下调用析构函数也是如此.调用delete之后,我仍然可以访问成员函数,但是成员变量为空(全部为0).而且我不能将delete加倍.请对此进行解释.

I have a piece of code where I can call the destructor multiple times and access member functions even the destructor was called with member variables' values preserved. I was still able to access member functions after I called delete but the member variables were nullified (all to 0). And I can't double delete. Please kindly explain this.

#include <iostream>
using namespace std;

template <typename T>
void destroy(T* ptr)
{
    ptr->~T();
}

class Testing
{
public:
    Testing() : test(20)
    {

    }

    ~Testing()
    {
        printf("Testing is being killed!\n");
    }

    int getTest() const
    {
        return test;
    }

private:
    int test;
};

int main()
{
    Testing *t = new Testing();
    cout << "t->getTest() = " << t->getTest() << endl;

    destroy(t);
    cout << "t->getTest() = " << t->getTest() << endl;

    t->~Testing();
    cout << "t->getTest() = " << t->getTest() << endl;

    delete t;
    cout << "t->getTest() = " << t->getTest() << endl;

    destroy(t);
    cout << "t->getTest() = " << t->getTest() << endl;

    t->~Testing();
    cout << "t->getTest() = " << t->getTest() << endl;

    //delete t; // <======== Don't do it! Double free/delete!
    cout << "t->getTest() = " << t->getTest() << endl;

    return 0;
}

这是未定义行为的表现.通过已删除的指针调用成员函数,一切顺利-不需要编译器和运行时检查此错误,但您当然不能指望这种工作.

This is an exhibit of undefined behavior. Call a member function through a pointer that's been deleted and anything goes - the compiler and runtime aren't required to check for this error, but you certainly can't count on this working.

这与使用已释放的内存属于相似的类别-您可能在那里找到了旧数据(或可能没有找到).您可能会导致程序崩溃(或不会崩溃).您甚至可以更改数据而无任何抱怨.

This falls into a similar category as using memory that's been freed - you might find your old data there (or you might not). You might cause the program to crash (or not). You might even be able to change the data without anything complaining.

但是无论如何,这是编程错误.

But in any case, it's a programming error.