【C++ 筆記】this pointer - part 21 === 目錄(Table of Contents): [TOC] --- 很感謝你點進來這篇文章。 你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧! this 指針(this pointer) --- 在 C++ OOP 中,每當呼叫非靜態成員函數時,編譯器會傳遞一種特殊的指標,稱為 "this" 指標。 它特殊的點就在於:它是隱形的。也就是說我們平常在設計 class 的時候,並不會看見 this pointer。 :::success this pointer 指向當前呼叫該函數的物件實例,讓程式可以在成員函數內部存取該物件的成員變數與其他成員函式。 ::: :::success 在 C++ 中,每個物件都能透過 this 指標來存取自己的位址。 ::: :::info Friend Function 沒有 this pointer,因為 Friend 不是類的成員,只有成員函數才有 this 指針。 ::: ### this pointer 是拿來幹嘛的? --- 具以下三種用途: 1. 辨識當前的物件 this pointer 代表正在執行函數的物件本身,使得在函數內部能明確區分物件成員與區域變數或參數。 如:在成員函數中若參數名稱與成員變數相同,利用 `this->` 可避免命名衝突。 2. 鏈式呼叫(OOP的一個專有名詞) 在運算子重載或方法設計中,常需回傳物件本身以實現鏈式運算(chaining)。透過 `return *this;`,可以讓呼叫者連續呼叫多個成員函式。 鏈式呼叫相關資訊:https://zh.wikipedia.org/zh-tw/%E6%96%B9%E6%B3%95%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8 3. 防止自我指定 在指定運算子等運算中,this pointer 可檢查是否為自我賦值(指定),避免不必要的運算跟潛在錯誤。 ### 為了要理解 this pointer,我們必須要知道... --- * 每個物件都有自己的資料成員副本。 每個物件都有自己的資料成員副本,所有物件共享一份成員函數的副本。 那麼現在的問題是,如果每個成員函數只有一份副本,並被多個物件使用,則如何正確存取和更新資料成員? 這就需要依靠 this pointer 的機制了。 * this pointer 在靜態成員函數中不可用,因為靜態成員函數可以不使用任何物件(用類名)來呼叫。 ### this pointer 的使用說明書 --- 在每個非靜態成員函數中,this pointer 都是隱式存在的,其型態依照函數是否為常數成員而有所不同: * 非 const 成員函數:型態為 `ClassName*`。 * const 成員函數:型態為 `const ClassName*`。 使用 this pointer 時,可透過 `this->` 存取物件的成員,如下: ```cpp= class MyClass { public: int value; MyClass(int value) : value(value) {} // 使用 this pointer 避免參數與成員名稱衝突 void setValue(int value) { this->value = value; } // 回傳物件本身以支援鏈式呼叫 MyClass& increment() { ++(this->value); return *this; } }; ``` * setValue 函數使用 this->value 來明確指定要修改的是物件的成員變數,而非函式參數。 * increment 函數透過回傳 *this,使得可進行連續的呼叫,如 `obj.increment().increment();`。 範例:運算子重載(鏈式呼叫) --- ```cpp= #include <iostream> using namespace std; class Counter { private: int count; public: Counter(int c = 0) : count(c) {} // 賦值運算子重載:利用 this 檢查自我賦值,並回傳物件本身以支援鏈式賦值 Counter& operator=(const Counter& other) { if (this != &other) { // 防止自我賦值 this->count = other.count; } return *this; } // 增加計數,並回傳物件本身 Counter& increment() { ++(this->count); return *this; } // 顯示目前計數 void display() const { cout << "Count: " << count << endl; } }; int main() { Counter a(5), b; b = a; b.increment().increment(); // 鏈式呼叫:連續增加兩次 a.display(); // 輸出:Count: 5 b.display(); // 輸出:Count: 7 return 0; } ``` * 第 31 行,用到了 this pointer 來比較物件位址,避免將自己賦值給自己(自我賦值)。 * `increment` 函數使用 `++(this->count)` 增加計數,並回傳 `*this` 使得可以連續呼叫。 * 第 33 行,使用鏈式呼叫,將物件 b 的計數從 5 增加到 7。 參考資料 --- ['this' pointer in C++ - GeeksforGeeks](https://www.geeksforgeeks.org/this-pointer-in-c/) [C++ 中的 this 指针 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-this-pointer.html) [[C++] this 指標 – 科技讀蟲](https://yhtechnote.com/this-pointer/) [this指標 | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/this-pointer?view=msvc-170)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up