ch4 – Smart Pointers 前言
raw pointer 的缺點
1. 以 raw pointer 而言,我們不知道他指向的是 single object 還是 array (表示法相同)
都是 object*,我們沒有辦法直接區分出來。
但為了簡化例子,我們以下使用 int 代替,但就沒辦法舉例到 single-object 的 delete。
- 以下是 int array 的宣告
int* p = new int[0]; // accessing p[0] or *p is undefined
delete[] p; // cleanup still required
- 以下是 int pointer 的宣告
#include <iostream>
using namespace std;
int main(){
int n = 1;
int* p1 = &n;
cout << *p1 << endl;
int a[3] = {1, 2, 3};
int* p2 = a;
cout << p2[1] << endl;
int* p3 = new int[5]; // accessing p[0] or *p is undefined
cout << p3[1] << endl;
p3[1] = 10;
cout << p3[1] << endl;
delete[] p3; // cleanup still required
return 0;
}
p1, p2 沒有使用到 new, 單純的拿地址,我們不需要寫 delete,
p3 使用了 new 宣告了 int array 這個 object,
我們需要手動 delete p3
- 結果
2. raw pointer 我們需要手動進行 destroy,換言之我們可能會忘記要 delete
這個很直覺,有 new,就必須要在另外寫一個 delete,
這就不是很方便。
3. raw pointer 可能會有專用的 destruction,我們也必須傳入
我們應該要使用 delete,或使用 dedicated (專用的) destruction,
這是我們必須決定的。
4. 與第一點相同的,raw pointer 我們在 delete 時,是 single-object 或是 array ?
與第一點相同的,raw pointer 我們在 delete 時,是 single-object 或是 array ?
- single-object 要使用 delete
- 而 array 要使用 delete[]
因為表示方法相同,所以我們沒辦法知道。
5. (未知的行為) raw pointer 因為手動 delete 的關係,我們可能會有不小心多次 delete 的情況
這其實比想像中容易發生,對於同一個物件的多次 delete,可能會有未知的行為。
obj* a;
if(condition){
// Do something...
delete a;
}
delete a;
我們不知道可能會發生什麼事。
6. (未知的行為) raw pointer 可能會創造出 dangling pointer,也不知道會發生什麼事
我們先來定義 dangling pointer,
通常我們會有一個 pointer 指向一個物件 (與其對應的記憶體位置)
pointer -> object(與對應的 memory 位置)
當 object 基於某些原因已經被 destroy,而這個仍然指向他的 pointer 就會被稱作 dangling pointer
dangling pointer -> 已 destroy object(對應的 memory 位置)
這個 pointer 依然指向這個記憶體位置,如果這時候我們使用了對這個 pointer 取值,
會發生什麼事情我們無法預期。
總結上述,我們發現 raw pointer 有太多細節需要注意,
雖然稍加注意就可以防範,但我們必須非常謹慎使用才行
smart pointer 的出現
C++11 後,smart pointer 的出現,
基本上我們可以視為他是「原來 raw pointer 的 wrapper」,