我只是写了一个示例程序来查看删除这个行为
class A { ~A() {cout << "In destructor \n ";} public: int a; A() {cout << "In constructor \n ";} void fun() { cout << "In fun \n"; delete this; cout << this->a << "\n"; // output is 0 this->fun_2(); // how m able to call fun_2, if delete this is called first ?? } void fun_2() { cout << "In fun_2 \n"; } main() { A *ptr = new A; ptr->a = 100; ptr->fun(); //delete this will be executed here ptr->fun_2(); //how m able to execute fun_2 when this pointer is deleted ?? cout<< ptr->a << "\n"; //prints 0 return 0; } > Output In constructor In fun In destructor 0 In fun 2 In fun 2 0
问题
m使用linux ubuntu和g ++编译器
让我们来比较一下类似的szenario:
A * a = new A();
FUNC(一);
删除一个;
FUNC2(一);
在我的示例中,编译器只是将指针a传递给func和func2,它并不关心它是否指向一个有效的对象。 所以如果你调用func2(a)而func2引用指针,这是未定义的行为。 如果内存被释放回操作系统,程序可能会崩溃,程序无法再访问* a。 通常删除保持内存分配,不传递给操作系统,所以访问* a后删除不会给出例外,但只是返回任何值。 这可能是以前的* a值,但也可能是其他值,具体取决于delete的实现方式,取决于delete a
和*a
之间的其他新调用。 例如,MSVC在调试模式下将内存设置为预定义的模式,以便您可以轻松地识别何时访问释放的内存。
为什么这与你的问题有关? 因为编译器把this
作为一个隐含的隐式参数传递。
Eric Lippert在函数返回后提供了一个有关指向局部变量指针的问题的类比方法,提供了一本非常好的“宾馆房间表格抽屉中的书”,这里同样适用。