C++靜態(tài)成員函數(shù)和this指針詳解
靜態(tài)成員
靜態(tài)成員就是在成員變量和成員函數(shù)前加上關(guān)鍵字static,稱為靜態(tài)成員
靜態(tài)成員分為:
1.靜態(tài)成員變量
所有對(duì)象共享同一份數(shù)據(jù) 在編譯階段分配內(nèi)存 類內(nèi)聲明,類外初始化
示例:
#include<iostream> using namespace std; class Person { public: static int m; // 所有對(duì)象共享同一份數(shù)據(jù) }; int Person::m = 0;// 類內(nèi)聲明,類外初始化
2.靜態(tài)成員函數(shù)
所有對(duì)象共享一個(gè)函數(shù) 靜態(tài)成員函數(shù)只能訪問(wèn)靜態(tài)成員變量
#include<iostream> using namespace std; class Person { public: static void func() { cout << "static void func調(diào)用" << endl; m_a = 100;//靜態(tài)成員函數(shù)可以訪問(wèn)靜態(tài)成員變量 //m_b=100,靜態(tài)成員函數(shù)不可以訪問(wèn)非靜態(tài)成員變量 //原因無(wú)法區(qū)分到底哪個(gè)是對(duì)象的m_b; } static int m_a;//靜態(tài)成員變量 int m_b; }; int Person::m_a = 0; int main() { //1.通過(guò)對(duì)象訪問(wèn) Person p; p.func(); //2.通過(guò)類名訪問(wèn) Person::func(); system("pause"); return 0; }
靜態(tài)成員函數(shù)可以訪問(wèn)靜態(tài)成員變量
靜態(tài)成員函數(shù)不可以訪問(wèn)非靜態(tài)成員變量
私有權(quán)限的靜態(tài)成員函數(shù),也是訪問(wèn)不到的
成員變量和成員函數(shù)分開(kāi)存儲(chǔ)
在C++中,類內(nèi)的成員變量和成員函數(shù)分開(kāi)存儲(chǔ)
只有非靜態(tài)成員變量才屬于類的對(duì)象上
空對(duì)象:
#include<iostream> using namespace std; class Person { }; void test01() { Person p; //空對(duì)象占用內(nèi)存空間為:1 //C++編譯器會(huì)給每個(gè)空對(duì)象也分配一個(gè)字節(jié)空間,是為了區(qū)分空對(duì)象占內(nèi)存的位置 //每個(gè)空對(duì)象也應(yīng)該有獨(dú)一無(wú)二的內(nèi)存地址 cout << sizeof(p) << endl; } int main() { test01(); return 0; }
輸出結(jié)果:1
#include<iostream> using namespace std; class Person { int m_a;//非靜態(tài)成員變量 屬于類的對(duì)象上 }; void test02() { Person p; cout << sizeof(p) << endl; } int main() { test02(); }
輸出結(jié)果:4
#include<iostream> using namespace std; class Person { int m_a;//非靜態(tài)成員變量 屬于類的對(duì)象上 static int m_b; //靜態(tài)成員變量 不屬于類的對(duì)象上 }; void test02() { Person p; cout << sizeof(p) << endl; } int main() { test02(); }
輸出結(jié)果:4
與第二個(gè)對(duì)比可知:
靜態(tài)成員變量 不屬于類的對(duì)象上
#include<iostream> using namespace std; class Person { int m_a;//非靜態(tài)成員變量 屬于類的對(duì)象上 static int m_b; //靜態(tài)成員變量 不屬于類的對(duì)象上 void func() {}//非靜態(tài)成員函數(shù) 不屬于類的對(duì)象上 static void func2() {} //靜態(tài)成員函數(shù)也不會(huì)屬于 類的對(duì)象上 }; int Person::m_b = 0; void test02() { Person p; cout << sizeof(p) << endl; } int main() { test02(); }
輸出結(jié)果:4
結(jié)論:只有非靜態(tài)成員變量才屬于類的對(duì)象上
this 指針
每一個(gè)非靜態(tài)成員函數(shù)只會(huì)誕生一份函數(shù)實(shí)例,也就是說(shuō)多個(gè)同類型的對(duì)象會(huì)共用一塊代碼
那么問(wèn)題是:這塊代碼是如何區(qū)分是哪個(gè)對(duì)象調(diào)用自己的呢?
C++通過(guò)提供的特殊的對(duì)象指針,this指針,解決上述問(wèn)題,this 指針指向被調(diào)用的成員函數(shù)所屬的對(duì)象,通俗的說(shuō),誰(shuí)調(diào)用它,this就指向誰(shuí)
this 指針是所有成員函數(shù)的隱含參數(shù)嗎,不需要定義,可直接使用
this 指針的用途
1.當(dāng)形參和成員變量同名時(shí),可用this指針來(lái)區(qū)分 2.在類的非靜態(tài)成員函數(shù)中返回對(duì)象本身,可用 return *this
1.當(dāng)形參和成員變量同名時(shí),可用this指針來(lái)區(qū)分
#include<iostream> using namespace std; class Person { public: void func(int age) { this->age = age; // } int age; }; int main() { Person p; p.func(18); cout << p.age << endl; system("pause"); return 0; }
2.在類的非靜態(tài)成員函數(shù)中返回對(duì)象本身,可用 return *this
#include<iostream> using namespace std; class Person { public: Person& func(Person&p) { this->age += p.age; return *this; } int age; }; int main() { Person p; p.age = 10; //鏈?zhǔn)骄幊趟枷? p.func(p).func(p).func(p); cout << p.age << endl; system("pause"); return 0; }
空指針訪問(wèn)成員函數(shù)
C++中空指針是可以調(diào)用成員函數(shù),但是也要注意有沒(méi)有用到this指針
如果用到this指針,需要加以判斷保證代碼的健壯性
#include<iostream> using namespace std; class Person { public: void ShowPersonclass() { cout << "調(diào)用ShowPerclass()函數(shù)" << endl; } }; int main() { Person* p = NULL; p->ShowPersonclass(); system("pause"); return 0; }
通過(guò)空指針p是可以訪問(wèn)到成員函數(shù)(不帶this指針的成員函數(shù))
如下代碼就是一個(gè)錯(cuò)誤代碼
#include<iostream> using namespace std; class Person { public: void ShowPersonname() { cout << m_name << endl; //此處出現(xiàn)了this指針 } int m_name; }; int main() { Person* p = NULL; p->ShowPersonname(); system("pause"); return 0; }
解析:
此處出現(xiàn)了this指針
cout << m_name << endl;
相當(dāng)于
cout <<this -> m_name << endl;
而this指針是一個(gè)空指針,所以會(huì)報(bào)錯(cuò)
為了增加代碼的健壯性,我們因該做出如下改動(dòng)
#include<iostream> using namespace std; class Person { public: void ShowPersonname() { if (this == NULL) //在此判斷this是否是空指針 return; cout << m_name << endl; } int m_name; }; int main() { Person* p = NULL; p->ShowPersonname(); system("pause"); return 0; }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
基于C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的音樂(lè)系統(tǒng)
C++中的Beep 函數(shù)是一個(gè)發(fā)出嗡鳴聲的函數(shù),本文將利用這個(gè)函數(shù)實(shí)現(xiàn)制作一個(gè)簡(jiǎn)單的聲音系統(tǒng)。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-12-12深入理解goto語(yǔ)句的替代實(shí)現(xiàn)方式分析
本篇文章是對(duì)goto語(yǔ)句的替代實(shí)現(xiàn)方式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05一起來(lái)看看C語(yǔ)言的預(yù)處理注意點(diǎn)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的預(yù)處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03C++實(shí)現(xiàn)統(tǒng)計(jì)代碼運(yùn)行時(shí)間的示例詳解
這篇文章主要為大家詳細(xì)介紹了C++一個(gè)有趣的小項(xiàng)目——統(tǒng)計(jì)代碼運(yùn)行時(shí)間,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05