---
# System prepended metadata

title: 【C++ 筆記】this pointer - part 21
tags: [物件導向程式設計, 程式設計, C++, 程式語言, OOP]

---

【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)