網站首頁 編程語言 正文
成員屬性和函數的存儲
在C++中成員變量和成員函數是分開存儲的;
空對象
class Person {};
這里我直接創建一個空的類,并創建一個空的類對象(Person p),利用sizeof關鍵字輸出p所占內存空間,sizeof(p);結果是p=1;
注意:空對象占用內存空間為:
1、C++編譯器會給每個空對象分配一個字節空間,是為了區分空對象占內存的位置
2、每個空對象也應該有一個獨一無二的內存地址
成員屬性的存儲
class Person
{
public:
int m_A;
static int m_B;
};
int Person::m_B = 100;
首先創建一個簡單的Person類,僅僅包含普通成員屬性m_A和靜態成員變量m_B;然后直接利用sizeof關鍵字輸出p所占內存空間:sizeof(p)
這里的結果是4,而不是8,這是因為靜態成員屬性不屬于類的對象上,無論再加幾個靜態成員屬性,都不會改變結果是4,但是一旦普通成員屬性,就會多占用內存空間,比如我加一個float類型的m_c屬性,結果是:
成員函數的存儲
class Person
{
public:
void func1(){}
static void func2(){}//函數都不屬于類的對象上,只有非靜態成員變量才占用類對象內存空間.
};
這里的Person類中加了普通成員函數和靜態成員函數,他們所占內存空間的情況是什么呢,讓我們看看結果:
為什么結果和空對象一樣呢,因為我開頭就說了,C++中成員變量和成員函數是分開存儲的,無論是怎樣的成員函數都不會占用類對象的內存空間。
小結:函數都不屬于類的對象上,只有非靜態成員變量才占用類對象內存空間.
this指針的概念
從上面的內容我們知道C++中成員變量和成員函數是分開存儲的,每一非靜態成員函數只會誕生一份函數實例,也就是說,多個同類型的對象會公用一塊代碼。
那么問題是:這一塊代碼是如何區分哪個對象調用自己呢?C++通過特殊的對象指針,this指針解決上述問題。this指針指向被調用的成員函數所屬的對象。 this指針是隱含每一個非靜態成員函數內的一個指針,不需要定義,直接使用即可。
作用:
1、解決名稱沖突
2、返回對象指針*this
解決名稱沖突
class Person
{
public:
Person(int age)
{
//this 指針指向 被調用的成員函數 所屬的對象
this->age = age;
}
int age;
};
如果我們在編寫代碼的時候,寫的屬性太多了,導致成員屬性和要傳入的變量名相同,就會引發不必要的bug;這時候加上一個this,就可以完美的解決這個問題,this->+屬性名,表示指向被調用的成員函數所屬的對象,那樣我們這個有參構造函數的賦值問題就很好的解決了。
返回對象指針*this
class Person
{
public:
Person(int age)
{
this->age = age;
}
Person(const Person& p)
{
cout << "拷貝構造函數調用" << endl;
cout << &p << endl;
}
Person& PersonAddAge(Person &p);
int age;
};
Person& Person::PersonAddAge(Person &p)//返回引用形式地址不變,可以一直加年齡
{
this->age += p.age;
cout << &*this << endl;
return *this;
}
既然this指針指向這個對象的地址,那么*this就代表這個對象的本身,我們做一個年齡相加的成員方法來測試一下;
void test02()
{
Person p1(10);
Person p2(10);
//p1.PersonAddAge(p2).PersonAddAge(p2);//鏈式調用,返回不加&結果都是20,調用拷貝構造;
p1.PersonAddAge(p2).PersonAddAge(p2).PersonAddAge(p1).PersonAddAge(p1);
cout << "p1 年齡為:" << p1.age;
}
大家可以猜猜這樣輸出的p1的年齡是多少,正確答案是120,其中的“.+函數”屬于鏈式調用,可以快速調用函數,非常之方便好用。之所以是120,原因是這四次調用中,第一次返回p1的年齡屬性為10+10,第二次為20+10,第三次為30+30,第四次為60+60=120。是不是看著很簡單,但有一個特別注意的事情;相信有心的伙伴已經看到PersonAddAge函數返回值類型是Person &,返回的是類的引用,為什么不返回類的值呢?
這里注意,如果去掉“&”直接返回類的值的話,是沒法繼續鏈式調用的,因為前面講過返回類型為類對象時,這個返回的類對象會被清理掉,然后調用拷貝構造函數在新的地址創建一個類對象,雖然屬性結果一樣,但是地址變了,可以輸出地址看看:
由此可見,去掉“&”四次調用產生了四個地址,而無論多用多少次增加年齡函數,最終結果也只能是20,因為我們輸出的是p1的值,從第二次調用,都和p1沒關系了,地址已經變了。
再和返回引用的做一下對比:
顯而易見,返回類引用不會調用構造函數,p1的地址不變,就能成功的累加年齡了!!!
總結
學習了這一節我們一定要知道C++成員屬性和成員函數是分開存儲的,以及this指針的妙用;再使用返回對象指針*this的時候,如果想繼續對此對象的屬性進行修改,一定要加上“&”引用符,如果單純為了顯示的話,可以不加。好了,今天的分享結束了,我們“明天見”。
原文鏈接:https://blog.csdn.net/m0_58618795/article/details/124974080
相關推薦
- 2024-02-26 啟動zabbix服務報“./zabbix_agentd: cannot execute binary
- 2022-10-24 利用Pandas求兩個dataframe差集的過程詳解_python
- 2022-05-04 C語言中getchar()的原理以及易錯點解析_C 語言
- 2022-09-07 Python和C語言利用棧分別實現進制轉換_python
- 2022-09-13 Android四大組件之Service服務詳細講解_Android
- 2022-03-27 centos7安裝mongo數據庫的方法(mongo4.2.8)_MongoDB
- 2021-12-18 linux下安裝redis圖文詳細步驟_Redis
- 2022-04-18 python?dataframe實現統計行列中零值的個數_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支