C++學(xué)習(xí)進(jìn)階篇之類大小計(jì)算和this指針
一、類大小計(jì)算
類的大小是只計(jì)算它的成員變量或者自定義成員,不會(huì)計(jì)算它的成員函數(shù)大小。
#include<iostream> using namespace std; class A1 { public: void fun() { _a = 1; _b = 2; } int _a; int _b; }; int main() { cout << sizeof(A1) << endl;//8字節(jié),為何是8字節(jié) return 0; }
光是類中成員變量_a,_b所占的字節(jié)大小就為8了,但是類中還要成員函數(shù),為何還是8字節(jié) 難道成員函數(shù)沒有在類之中,對(duì)的
類成員函數(shù)在公共代碼區(qū)的,不同對(duì)象的成員數(shù)據(jù)是私有的每個(gè)人有自己的成員數(shù)據(jù)
但是成員函數(shù)是共有的,此時(shí)別人也可以用,所有它們并不是都要有成員函數(shù)成員函數(shù)反而占用更多的空間
類定義對(duì)象之后,相當(dāng)于小區(qū)房子,每個(gè)房子都有廚房,臥室(相當(dāng)于數(shù)據(jù))
但是這些房子不一定要有籃球場(相當(dāng)于成員函數(shù)),如果每一個(gè)房子都有籃球場可想而知這個(gè)房子占地會(huì)有多大
其次籃球場得很多人來玩籃球澀,不可能每次都是你一個(gè)人玩,無不無聊,得喊朋友鄰居一起,這些朋友鄰居也能玩
還不如將其修在小區(qū)中心,這樣大大節(jié)省了空間 而類它的成員函數(shù)就是放在公共代碼區(qū)的,所以不占用類空間大小
空類或者只有成員函數(shù)時(shí),類大小?
1字節(jié)大小,它占個(gè)位,雖然一個(gè)房子它可能什么都么有但是它難道就不是房子了嗎,起碼那塊地還是一個(gè)房子,理應(yīng)有一個(gè)位置
#include<iostream> using namespace std; class A1//類中只有成員函數(shù) { void fun() {} }; class A2 {};//空類 int main() { cout << sizeof(A1) << endl; cout << sizeof(A2) << endl; A1 a; A2 b; //雖然里面什么都沒有但是這個(gè)位置是要在的 cout << &a << endl; cout << &b << endl; return 0; }
沒有成員變量的類對(duì)象,需要1byte是為了占位,表示對(duì)象存在
二、this指針
作為成員函數(shù)的隱形指針,接收對(duì)象地址
#include<iostream> using namespace std; class day { public: void init(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { //cout << this->_year << '-' << this->_month << '-' << this->_day << endl; cout << _year << '-' <<_month << '-' << _day << endl; } int _year; int _month; int _day; }; int main() { day d1; day d2; d1.init(2023, 4, 24); d2.init(2022, 4, 24); d1.Print(); d2.Print(); return 0; }
雖然兩個(gè)對(duì)象初始化不同,但是我在調(diào)用打印函數(shù)時(shí),實(shí)參可是什么都沒傳,都是call同一個(gè)地址,為何結(jié)果卻不同?
既然類中的成員函數(shù)是放在公共代碼區(qū)的,不在對(duì)象總,這個(gè)函數(shù)的地址是固定的,
那么為何兩個(gè)對(duì)象調(diào)用它(函數(shù))時(shí)所得結(jié)果會(huì)不一樣(都是call同一個(gè)地址)
是因?yàn)閷?duì)象在調(diào)用時(shí)編譯器隱含的將對(duì)象的地址作為實(shí)參給傳了過去,而函數(shù)形參隱含用this指針接收 在調(diào)用時(shí),默認(rèn)將對(duì)象地址當(dāng)作實(shí)參傳過去
調(diào)試程序,然后右擊鼠標(biāo),點(diǎn)擊轉(zhuǎn)到反匯編,查看匯編代碼
這些匯編代碼是在將實(shí)參壓棧
可以發(fā)現(xiàn)原本調(diào)用成員函數(shù)Init時(shí)只是顯式傳了三個(gè)實(shí)參,但是在底層匯編指令卻壓了四個(gè)參數(shù),那是因?yàn)閷?duì)象的地址作為實(shí)參隱含壓棧
在壓棧時(shí),會(huì)將對(duì)象的地址作為實(shí)參壓棧傳給它所調(diào)用的成員函數(shù)
在vs下面,對(duì)this指針傳遞進(jìn)行了優(yōu)化,將對(duì)象的地址放在寄存器(rcx)中,寄存器(rcx)存this指針的值
Print這里有隱含對(duì)象形參指針的,但是不能將其顯式的寫出來
不可修改this指針指向的對(duì)象,因?yàn)閠his是被const修飾(相當(dāng)于day*const this
)它的指向?qū)ο蟛豢杀恍薷?br />但是它指向?qū)ο蟮膬?nèi)容可以被修改
也可以通過this指針訪問對(duì)象成員變量
雖然成員函數(shù)形參this指針不能顯式寫出
但是在成員函數(shù)內(nèi)要訪問對(duì)象中成員變量時(shí)卻可以顯示寫出
可不可以這樣訪問類的成員變量?
不可這樣直接訪問,就算是類所以成員都是對(duì)外開放的,但是類中的成員變量只是聲明了,并沒有將其實(shí)例化,相當(dāng)于房子,只拿著一張圖紙,你就想在現(xiàn)實(shí)世界找到對(duì)應(yīng)的房間,抱歉不可能
那么可不可以這樣直接調(diào)用類的成員函數(shù)?
這種直接在類中調(diào)用它的成員函數(shù),其實(shí)是不行的,因?yàn)檫@都沒有定義出對(duì)象,編譯器在調(diào)用Print函數(shù)時(shí)是會(huì)隱晦的將對(duì)象地址當(dāng)作實(shí)參傳過去,這里連對(duì)象都沒有如何調(diào)用?
那么有人又會(huì)說,那我傳空地址可否?在調(diào)用時(shí),對(duì)象地址是隱晦的壓棧,并不能顯式的寫出來,也是不行的
#include<iostream> using namespace std; class day { public: void init(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { cout << this->_year << '-' << this->_month << '-' << this->_day << endl; } int _year; int _month; int _day; }; int main() { day* p = nullptr; p->init(2023, 4, 24); p->Print(); }
p->initp調(diào)用函數(shù)init會(huì)對(duì)這個(gè)函數(shù)解引用嗎?不會(huì),因?yàn)檫@個(gè)函數(shù)的地址不在這個(gè)對(duì)象中,它在公共代碼區(qū) p會(huì)作為實(shí)參傳給this指針
雖然定義類對(duì)象是為空的指針,但是調(diào)用類成員初始化函數(shù),并沒有報(bào)錯(cuò),是因?yàn)闆]有訪問對(duì)象中的成員變量
這樣會(huì)發(fā)生錯(cuò)誤,因?yàn)樵L問對(duì)象中的成員,但是this指針的值為空,對(duì)空指針解引用,這樣極其危險(xiǎn)的操作
總結(jié)
到此這篇關(guān)于C++學(xué)習(xí)進(jìn)階篇之類大小計(jì)算和this指針的文章就介紹到這了,更多相關(guān)C++類大小計(jì)算和this指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中重載、重寫(覆蓋)和隱藏的區(qū)別實(shí)例分析
這篇文章主要介紹了C++中重載、重寫(覆蓋)和隱藏的區(qū)別,是C++面向?qū)ο蟪绦蛟O(shè)計(jì)非常重要的概念,需要的朋友可以參考下2014-08-08C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07vc中float與DWORD的互想轉(zhuǎn)換實(shí)現(xiàn)代碼
這篇文章主要介紹了vc中float與DWORD的互想轉(zhuǎn)換實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-06-06C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié),包括正弦和雙曲線正弦以及反正弦的函數(shù),需要的朋友可以參考下2015-08-08C++實(shí)現(xiàn)獲取IP、子網(wǎng)掩碼、網(wǎng)關(guān)、DNS等本機(jī)網(wǎng)絡(luò)參數(shù)的方法
這篇文章主要介紹了C++實(shí)現(xiàn)獲取IP、子網(wǎng)掩碼、網(wǎng)關(guān)、DNS等本機(jī)網(wǎng)絡(luò)參數(shù)的方法,需要的朋友可以參考下2014-07-07C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例
下面小編就為大家分享一篇C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12