C++ this指針和空指針的具體使用
每一個(gè)非靜態(tài)成員函數(shù)只會誕生一份函數(shù)實(shí)例,也就是說多個(gè)同類型的對象會共用一塊代碼那么問題是:這—塊代碼是如何區(qū)分那個(gè)對象調(diào)用自己的呢?
C++通過提供特殊的對象指針,this指針,解決上述問題。this指針指向被調(diào)用的成員函數(shù)所屬的對象
this指針是隱含每一個(gè)非靜態(tài)成員函數(shù)內(nèi)的—種指針
this指針不需要定義,直接使用即可
this指針的用途:
- 當(dāng)形參和成員變量同名時(shí),可用this指針來區(qū)分
- 在類的非靜態(tài)成員函數(shù)中返回對象本身,可使用return this
一、this指針
1 this指針解決名稱沖突
#include <iostream> using namespace std; class Person { public: Person(int age) { age = age; } int age; }; //1 解決名稱沖突 void test1() { Person p1(18); cout << "p1的年齡為=" << p1.age << endl; } int main() { test1(); return 0; }
輸出年齡亂碼
分析
光標(biāo)放在形參age上,發(fā)現(xiàn)三個(gè)age 都是灰色,系統(tǒng)認(rèn)為這個(gè)三個(gè)age 是同一數(shù)據(jù)
解決1:
將成員變量和形參書寫是上加m_區(qū)分
class Person { public: Person(int age) { m_Age = age; } int m_Age; };
解決2:
this指針指向 被調(diào)用的成員函數(shù) 所屬對象
class Person { public: //1 解決名稱沖突 Person(int age) { //this指針指向 被調(diào)用的成員函數(shù) 所屬對象 this->age = age; } int age; };
2 返回對象本身用*this
class Person { public: //1 解決名稱沖突 Person(int age) { //this指針指向 被調(diào)用的成員函數(shù) 所屬對象 this->age = age; } //2 返回對象本身用*this void PersonAddAge(Person &p) { this->age += p.age; } int age; }; //1 解決名稱沖突 void test1() { Person p1(18); cout << "p1的年齡為=" << p1.age << endl; //2 返回對象本身用*this Person p2(10); p2.PersonAddAge(p1); cout << "p2的年齡為=" << p2.age << endl; }
現(xiàn)在想要年齡后面繼續(xù)累加,出錯(cuò)
函數(shù)test1()是void無返回值型,調(diào)用完畢就不能再調(diào)用了
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
如果每次調(diào)用完畢,可以返回到p2,就可以繼續(xù)再調(diào)用PersonAddAge(p1);
//2 返回對象本身用*this Person &PersonAddAge(Person &p) { //this指向p2的指針,而*this指向的就是p2這個(gè)對象的本體 this->age += p.age; return *this; }
完整代碼
#include <iostream> #include<string> using namespace std; //1 解決名稱沖突 //2 返回對象本身用*this class Person { public: //1 解決名稱沖突 Person(int age) { //this指針指向 被調(diào)用的成員函數(shù) 所屬對象 this->age = age; } //2 返回對象本身用*this Person &PersonAddAge(Person &p) { //this指向p2的指針,而*this指向的就是p2這個(gè)對象的本體 this->age += p.age; return *this; } int age; }; //1 解決名稱沖突 void test1() { Person p1(18); cout << "p1的年齡為=" << p1.age << endl; //2 返回對象本身用*this Person p2(10); p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); cout << "p2的年齡為=" << p2.age << endl; } int main() { test1(); return 0; }
二、空指針調(diào)用成員函數(shù)
C++中空指針也是可以調(diào)用成員函數(shù)的,但是也要注意有沒有用到this指針
如果用到this指針,需要加以判斷保證代碼的健壯性
#include<iostream> using namespace std; //空指針調(diào)用成員函數(shù) class Person { public: void showClassName() { cout << "This is Person class" << endl; } void showPersonAge() { //報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔? cout << "age=" <<m_Age<< endl; } int m_Age; }; void test1() { Person* p = NULL; p->showClassName(); // p->showPersonAge();//報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔? } int main() { test1(); return 0; }
//報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔?/p>
if(this==NULL) return; //解決空指針出錯(cuò)
void showPersonAge() { //報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔? if(this==NULL) return; //解決空指針出錯(cuò) cout << "age=" <<m_Age<< endl; }
完整代碼
#include<iostream> using namespace std; //空指針調(diào)用成員函數(shù) class Person { public: void showClassName() { cout << "This is Person class" << endl; } void showPersonAge() { //報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔? if(this==NULL) return; //解決空指針出錯(cuò) cout << "age=" <<m_Age<< endl; } int m_Age; }; void test1() { Person* p = NULL; p->showClassName(); p->showPersonAge();//報(bào)錯(cuò)原因是因?yàn)閭魅氲氖强罩羔? } int main() { test1(); return 0; }
三、const修飾成員函數(shù)
常函數(shù):
·成員函數(shù)后加const后我們稱為這個(gè)函數(shù)為常函數(shù)
.常函數(shù)內(nèi)不可以修改成員屬性
·成員屬性聲明時(shí)加關(guān)鍵字mutable后,在常函數(shù)中依然可以修改
常對象:
·聲明對象前加const稱該對象為常對象
·常對象只能調(diào)用常函數(shù)
解決方法:
成員屬性聲明時(shí)加關(guān)鍵字mutable,在常函數(shù)中才可以修改
mutable int m_B;//特殊變量,即使在常函數(shù)中,也可修飾這個(gè)值,加關(guān)鍵字mutable
//常函數(shù) class Person { public: //this指針的本質(zhì)是指針常量,指針的指向是不可以修改的 //const Person *const this; //在成員函數(shù)后面加const,修飾的是this指向,讓指針指向的值也不可以修改 void showPerson() const { // m_A = 100; //常函數(shù)內(nèi)不可以修改成員屬性 // this->m_A = 100; // this = NULL; m_B = 100; //成員屬性聲明時(shí)加關(guān)鍵字mutable,在常函數(shù)中才可以修改 } int m_A; mutable int m_B;//特殊變量,即使在常函數(shù)中,也可修飾這個(gè)值,加關(guān)鍵字mutable };
const Person p;//在對象前加const變常對象
//常對象 void test2() { const Person p;//在對象前加const變常對象 // p.m_A = 100;//報(bào)錯(cuò) p.m_B = 100;//m_B是特殊值,在常對象下也可以修改 //常對象只能調(diào)用常函數(shù) p.showPerson(); // p.func();//常對象不可以調(diào)用普通成員函數(shù),因?yàn)槠胀ǔ蓡T函數(shù)可以修改屬性 }
完整代碼
#include<iostream> using namespace std; //常函數(shù) //常對象 class Person { public: //this指針的本質(zhì)是指針常量,指針的指向是不可以修改的 //const Person *const this; //在成員函數(shù)后面加const,修飾的是this指向,讓指針指向的值也不可以修改 void showPerson() const { // m_A = 100; //常函數(shù)內(nèi)不可以修改成員屬性 // this->m_A = 100; // this = NULL; m_B = 100; //成員屬性聲明時(shí)加關(guān)鍵字mutable,在常函數(shù)中才可以修改 } void func() { } int m_A; mutable int m_B;//特殊變量,即使在常函數(shù)中,也可修飾這個(gè)值,加關(guān)鍵字mutable }; //常函數(shù) void test1() { Person p; p.showPerson(); } //常對象 void test2() { const Person p;//在對象前加const變常對象 // p.m_A = 100;//報(bào)錯(cuò) p.m_B = 100;//m_B是特殊值,在常對象下也可以修改 //常對象只能調(diào)用常函數(shù) p.showPerson(); // p.func();//常對象不可以調(diào)用普通成員函數(shù),因?yàn)槠胀ǔ蓡T函數(shù)可以修改屬性 } int main() { test1(); return 0; }
參考:黑馬程序員
嗶哩嗶哩 黑馬程序員
到此這篇關(guān)于C++ this指針和空指針的具體使用的文章就介紹到這了,更多相關(guān)C++ this指針和空指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++指針作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí)需要注意的一些問題
當(dāng)指針作為函數(shù)的參數(shù)進(jìn)行傳遞的時(shí)候,本質(zhì)上還是進(jìn)行的“值傳遞”,也就是復(fù)制了一個(gè)新的指向該地址的指針變量2013-10-10C++流程控制中用于跳轉(zhuǎn)的return和goto語句學(xué)習(xí)教程
這篇文章主要介紹了C++流程控制中用于跳轉(zhuǎn)的return和goto語句學(xué)習(xí)教程,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01C++共享智能指針shared_ptr的實(shí)現(xiàn)
在C++中沒有垃圾回收機(jī)制,必須自己釋放分配的內(nèi)存,否則就會造成內(nèi)存泄露,解決這個(gè)問題最有效的方法是使用智能指針,本文主要介紹了C++共享智能指針shared_ptr的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12C語言實(shí)現(xiàn)linux網(wǎng)卡檢測改進(jìn)版
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)linux網(wǎng)卡檢測的改進(jìn)版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06C++實(shí)現(xiàn)LeetCode165.版本比較)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode165.版本比較),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07