前言
本篇基於“delete this” in C++,並完善了原文中提供的幾個例子。
can only be used with new
只有當物件是使用new
創建的,我們才能使用delete this
來銷毀它。
定義一個名為A
的類別,函數fun
裡用到了delete this
:
class A{
public:
void fun(){
delete this;
}
};
使用new
創建一個A
類別的物件,並使ptr1
指向它。然後呼叫fun
這個函數,用來銷毀該物件:
A *ptr1 = new A;
ptr1->fun();
ptr1 = nullptr; // make ptr NULL to make sure that things are not accessed using ptr.
以上這段代碼可以執行無誤。
再來看一個例子,如果沒有用new
創建物件,卻使用了delete this
:
A a;
a.fun();
則會造成以下錯誤:
a.out(24779,0x1164e25c0) malloc: *** error for object 0x7ffee89ff718: pointer being freed was not allocated
a.out(24779,0x1164e25c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6
access member variable after delete this
在使用delete this
後,存取成員變數是undefined behavior。
下面定義了一個名為B
的類別。在建構子中會初始化它的三個成員變數。而在函數fun
中,則會在delete this
前後各輸出一次它的三個成員變數:
class B{
private:
int x;
std::string s;
std::vector<int> v;
public:
B(){
x = 100;
s = "abc";
v.push_back(x);
}
void fun(){
std::cout << "before delete this" << std::endl;
std::cout << x << std::endl;
std::cout << s << std::endl;
std::cout << v.size() << " " << v[0] << std::endl;
delete this;
/* Invalid: Undefined Behavior */
std::cout << "after delete this" << std::endl;
std::cout << x << std::endl;
std::cout << s << std::endl;
std::cout << v.size() << " " << v[0] << std::endl;
}
};
使用正確地方式來新建及銷毀B
類別的物件:
B *ptr2 = new B;
ptr2->fun();
ptr2 = nullptr;
輸出為:
before delete this
100
abc
1 100
after delete this
100
abc
0 0
因為在delete this
後存取成員變數是未定義的行為,所以我們可以看到,成員變數v
在delete this
前後並不一致。
以上兩個例子的代碼詳見cpp-code-snippets/delete_this.cpp。