C++ this 指針的具體使用
1.this指針的本質(zhì):一個(gè)隱藏的參數(shù)
首先,最關(guān)鍵的概念是:this 指針是一個(gè)隱含的、額外的參數(shù),由編譯器自動(dòng)添加到所有非靜態(tài)成員函數(shù)的參數(shù)列表中。
當(dāng)你定義一個(gè)成員函數(shù):
class MyClass {
public:
void setValue(int value) {
// ...
}
};編譯器在底層實(shí)際上會(huì)將它處理為類似這樣的形式:
void setValue(MyClass* this, int value) {
// ...
}而當(dāng)你通過一個(gè)對(duì)象調(diào)用這個(gè)函數(shù)時(shí):
MyClass obj; obj.setValue(10);
編譯器會(huì)將它處理為:
setValue(&obj, 10); // 將 obj 的地址作為第一個(gè)參數(shù)(this)傳入
這就是 this 指針的由來——它指向調(diào)用該成員函數(shù)的那個(gè)對(duì)象的地址
2.this指針的核心特性
類型:this 指針的類型是 ClassName* const(一個(gè)指向 ClassName 的常量指針)。這意味著 this 指針本身的值(即它存儲(chǔ)的地址)不能被修改(你不能讓 this 指向另一個(gè)對(duì)象),但它所指向的對(duì)象的內(nèi)容可以被修改。
在 const 成員函數(shù) 中,this 指針的類型變?yōu)?nbsp;const ClassName* const,這意味著你不能通過 this 修改對(duì)象的數(shù)據(jù)成員(除非成員被 mutable 修飾)。
作用域:this 指針在類的非靜態(tài)成員函數(shù)內(nèi)部是局部的。它不能在成員函數(shù)體之外使用或定義。
存儲(chǔ):this 指針本身是一個(gè)函數(shù)參數(shù),因此它通常存儲(chǔ)在棧上(或者寄存器中,取決于調(diào)用約定),而不是對(duì)象本身的一部分。
3.this指針的主要應(yīng)用場(chǎng)景
場(chǎng)景一:解決命名沖突(最經(jīng)典用法)
當(dāng)成員函數(shù)的參數(shù)名與類的數(shù)據(jù)成員名相同時(shí),使用 this 來明確指明要訪問的是當(dāng)前對(duì)象的數(shù)據(jù)成員。
class Person {
private:
std::string name;
int age;
public:
void setName(std::string name) { // 參數(shù)名與成員變量名相同
this->name = name; // 使用 this-> 來訪問成員變量
// name = name; // 錯(cuò)誤!這只是在給參數(shù)name自己賦值,成員變量未被修改
}
void setAge(int age) {
this->age = age;
}
};場(chǎng)景二:在成員函數(shù)中返回對(duì)象本身(用于鏈?zhǔn)秸{(diào)用)
通過返回 *this(對(duì) this 指針解引用),可以讓成員函數(shù)的調(diào)用串聯(lián)起來。
class Counter {
int count;
public:
Counter() : count(0) {}
// 返回 Counter& 非常重要,如果返回 Counter(值),鏈?zhǔn)秸{(diào)用中的每個(gè)操作都將作用于一個(gè)臨時(shí)副本
Counter& increment() {
count++;
return *this; // 返回當(dāng)前對(duì)象本身的引用
}
Counter& decrement() {
count--;
return *this;
}
int getCount() const { return count; }
};
int main() {
Counter c;
// 鏈?zhǔn)秸{(diào)用 (Chaining)
c.increment().increment().decrement();
std::cout << c.getCount() << std::endl; // 輸出 1
return 0;
}場(chǎng)景三:在成員函數(shù)中傳遞對(duì)象自身
當(dāng)你需要在成員函數(shù)內(nèi)部將當(dāng)前對(duì)象作為一個(gè)參數(shù)傳遞給其他函數(shù)時(shí)。
class Server; // 前向聲明
class Client {
public:
void sendDataTo(Server& srv);
};
class Server {
public:
void processRequest(Client& client) {
// ... 處理來自 client 的請(qǐng)求
}
};
void Client::sendDataTo(Server& srv) {
// 將當(dāng)前 Client 對(duì)象傳遞給 Server 的 processRequest 方法
srv.processRequest(*this); // 使用 *this 傳遞對(duì)象本身
}場(chǎng)景四:在數(shù)據(jù)結(jié)構(gòu)中實(shí)現(xiàn)自引用
在實(shí)現(xiàn)鏈表、樹等數(shù)據(jù)結(jié)構(gòu)時(shí),節(jié)點(diǎn)類中的成員函數(shù)經(jīng)常需要使用 this 來指代自身。
class ListNode {
public:
int data;
ListNode* next;
ListNode(int val) : data(val), next(nullptr) {}
// 在當(dāng)前節(jié)點(diǎn)后插入一個(gè)新節(jié)點(diǎn)
void insertAfter(int val) {
ListNode* newNode = new ListNode(val);
newNode->next = this->next; // 使用 this 明確表示當(dāng)前節(jié)點(diǎn)的 next 指針
this->next = newNode;
}
};4.this指針的注意事項(xiàng)和進(jìn)階知識(shí)
靜態(tài)成員函數(shù)沒有 this 指針:
靜態(tài)成員函數(shù)屬于類本身,而不屬于任何一個(gè)特定的對(duì)象。因此,它沒有this指針。這也意味著靜態(tài)成員函數(shù)不能直接訪問類的非靜態(tài)成員(因?yàn)闆]有對(duì)象實(shí)例可供操作)。this 指針與 Lambda 表達(dá)式:
在類的非靜態(tài)成員函數(shù)中定義的 Lambda 表達(dá)式,如果捕獲了this指針(顯式或隱式捕獲),就可以通過該指針訪問類的成員。
class MyClass {
int value = 42;
public:
void foo() {
// 捕獲 this 指針,從而可以訪問成員變量 value
auto lambda = [this]() {
std::cout << this->value << std::endl;
};
lambda();
}
};注意:如果 Lambda 的生命周期可能超過當(dāng)前對(duì)象(例如,被傳遞給另一個(gè)線程),捕獲 this 會(huì)導(dǎo)致懸空指針(Dangling Pointer),這是非常危險(xiǎn)的。在這種情況下,需要考慮弱引用或其他生命周期管理策略。
3.this 指針與智能指針:
當(dāng)你使用 std::shared_ptr 或 std::unique_ptr 管理對(duì)象時(shí),this 指針仍然是原始指針(raw pointer)。從一個(gè)共享指針管理的對(duì)象內(nèi)部獲取 this,并用它創(chuàng)建另一個(gè)共享指針,是極其錯(cuò)誤的,因?yàn)檫@會(huì)導(dǎo)致兩個(gè)獨(dú)立的控制塊,對(duì)象會(huì)被銷毀兩次。
C++標(biāo)準(zhǔn)庫提供了 std::enable_shared_from_this 來解決這個(gè)問題。
#include <memory>
class Good : public std::enable_shared_from_this<Good> {
public:
std::shared_ptr<Good> getptr() {
return shared_from_this(); // 正確地從 this 生成一個(gè) shared_ptr
}
};
int main() {
std::shared_ptr<Good> gp1 = std::make_shared<Good>();
std::shared_ptr<Good> gp2 = gp1->getptr(); // 正確,共享所有權(quán)
return 0;
}總結(jié)
| 特性/場(chǎng)景 | 描述 |
|---|---|
| 本質(zhì) | 編譯器自動(dòng)傳遞給非靜態(tài)成員函數(shù)的隱藏參數(shù),指向調(diào)用該函數(shù)的對(duì)象。 |
| 類型 | ClassName* const(在 const 函數(shù)中是 const ClassName* const)。 |
| 解決命名沖突 | 使用 this->member 區(qū)分同名的參數(shù)和成員變量。 |
| 鏈?zhǔn)秸{(diào)用 | 返回 *this(返回對(duì)象引用)以實(shí)現(xiàn) obj.func1().func2() 的流暢接口。 |
| 傳遞自身 | 使用 *this 將當(dāng)前對(duì)象作為參數(shù)傳遞給其他函數(shù)。 |
| 靜態(tài)函數(shù) | 沒有 this 指針,因此不能訪問非靜態(tài)成員。 |
| Lambda 捕獲 | 可以捕獲 this 來在 Lambda 內(nèi)部訪問成員,但需注意生命周期。 |
| 智能指針 | 直接使用 this 創(chuàng)建智能指針是危險(xiǎn)的,應(yīng)使用 std::enable_shared_from_this。 |
到此這篇關(guān)于C++ this 指針的具體使用的文章就介紹到這了,更多相關(guān)C++ this 指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(152.求最大子數(shù)組乘積)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(152.求最大子數(shù)組乘積),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++和python實(shí)現(xiàn)單鏈表及其原理
這篇文章主要介紹了C++和python實(shí)現(xiàn)單鏈表及其原理,單鏈表是鏈表家族中的一員,每個(gè)節(jié)點(diǎn)依舊由數(shù)據(jù)域(data)和指針域(next)組成,鏈表的具體概念下面文章將詳細(xì)介紹,需要的小伙伴可以參考一下2022-03-03

