分類

展開全部 | 收合全部

分類

展開全部 | 收合全部

【Effective Modern C++ 閱讀筆記 #1】ch4 – Smart Pointers 前言, 什麼是 dangling pointer?

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」,
而這個 warpper,幫我們迴避掉了上面多數缺點,使我們可以減少犯下的錯誤。

因此在 C++ 11 以後,
我們大部分都會推薦優先使用 smart pointer,
smart pointer 不但可以做到幾乎全部 raw pointer 能做到的事情,
還可以大幅減少因為不小心犯下的錯誤。

smart pointer 的種類

我們總共有四種 smart pointert 出現在 C++11 之後,分別有

  • std::auto_ptr
  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr

std::auto_ptr

其中,std::auto_ptr 已經被棄用,在 C++98 時因為 move semantics 還沒有出現,
因此他有使用 copy 的方式實現,總之就是還不完整設計,知道是個過渡性的東西就好,
後來在 C++ 11 後我們都使用 std::unique_ptr

std::unique_ptr 幾乎做到所有 std::auto_ptr 能做到的事情,
他還做得更多、更有效率,而且不是使用 copy 的方法

目前唯一我們還使用 std::auto_ptr 的情境就是為了配合 C++ 98 的 compiler,
不然建議一律改使用 std::unique_ptr

Reference

⭐C++ 基礎用法 相關文章整理⭐:
1.【C++】C++ compile 程式碼 使用 c++ 11 與使用相關的 package
2.【C++】C/C++ 顯示資料的類別 (type) sample code (內含範例程式碼) print C data type, cout C++ data type, get variable type in c++
3.【C++】C++ 複製 2D array的方法 copy 2d array memcpy sample code (內含範例程式碼)
⭐Modern C++ ⭐:
⭐C++ 字串處理相關文章整理⭐:
1.【C++】字串 char string stringstream 相關用法總整理 (內含範例程式碼) 與利用 sprinf, snprinf assign 值的方法
2.【C++】字串 char string stringstream 「轉換」用法總整理 (內含範例程式碼)
3.【C】printf, fprintf, sprintf, snprintf 相關用法總整理 (內含範例程式碼)
4.【C++】C++ String 用法 連接兩個 String c++ string concat
⭐C++ 系統偵測相關文章整理⭐:
1.【C++】C++ 利用 dirent.h 計算資料夾的檔案數量 count files sample code (內含範例程式碼)
2.【C++】C++ inotify sample code 偵測指定路徑底下的文件變化 (內有範例程式碼)
⭐C++ OpenCV 相關文章整理⭐:
1.【OpenCV】c++ OpenCV – 在 ubuntu 上第一次執行 OpenCV 程式 sample code (內含範例程式碼)
2.【OpenCV】c++ OpenCV - 在圖片上寫上文字 cv::putText sample code (內含範例程式碼)
3.【OpenCV】c++ OpenCV - cv::Rect 矩形用法與相關功能函數 sample code (內含範例程式碼)
4.【OpenCV】c++ OpenCV - OpenCV 中的純量 定義顏色 cv::Scalar(255,255,255) color sample code (內含範例程式碼)
5.【OpenCV】用 C++ 計算 iou 的方法 與網路算法常見錯誤(內附範例程式碼) sample code
⭐C++ Makefile 相關文章整理⭐:
1.【C++ Makefile】- 1 / 嘗試撰寫自己的第一份 Makefile
2.【C++ Makefile】- 2 / 新增自己的變數
3.【C++ Makefile】- 3 / Makefile 常用變數 -「$@」, 「$^」
4.【C++ Makefile】- 4 / Makefile 常用 fake target -「.PHONY」
5.【C++ Makefile】- 5 / Makefile 內建變數 -「$@」, 「$^」, 「$<」, 「$* 」,「$? 」
⭐【喜歡我的文章嗎? 歡迎幫我按讚~ 讓基金會請創作者喝一杯咖啡!
如果喜歡我的文章,請幫我在下方【按五下Like】 (Google, Facebook 免註冊),會由 「LikeCoin」 贊助作者鼓勵繼續創作,讀者們「只需幫忙按讚,完全不用出錢」哦!

likecoin-steps
Howard Weng
Howard Weng

我是 Howard Weng,很多人叫我嗡嗡。這個網站放了我的各種筆記。希望這些筆記也能順便幫助到有需要的人們!如果文章有幫助到你的話,歡迎幫我點讚哦!
另外,因為定位是「個人的隨手筆記」,有些文章內容「⚠️可能我理解有誤⚠️」或「?只寫到一半?」,如果有發現這樣的情況,歡迎在該文章的最下面留言提醒我!我會儘快修正或補上!感謝大家的建議與幫忙,讓網站能變得更好?

文章: 890

★留個言吧!內容有誤或想要補充也歡迎與我討論!