C++學習進階篇之類大小計算和this指針
一、類大小計算
類的大小是只計算它的成員變量或者自定義成員,不會計算它的成員函數(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ù)沒有在類之中,對的
類成員函數(shù)在公共代碼區(qū)的,不同對象的成員數(shù)據(jù)是私有的每個人有自己的成員數(shù)據(jù)
但是成員函數(shù)是共有的,此時別人也可以用,所有它們并不是都要有成員函數(shù)成員函數(shù)反而占用更多的空間
類定義對象之后,相當于小區(qū)房子,每個房子都有廚房,臥室(相當于數(shù)據(jù))
但是這些房子不一定要有籃球場(相當于成員函數(shù)),如果每一個房子都有籃球場可想而知這個房子占地會有多大
其次籃球場得很多人來玩籃球澀,不可能每次都是你一個人玩,無不無聊,得喊朋友鄰居一起,這些朋友鄰居也能玩
還不如將其修在小區(qū)中心,這樣大大節(jié)省了空間 而類它的成員函數(shù)就是放在公共代碼區(qū)的,所以不占用類空間大小
空類或者只有成員函數(shù)時,類大???
1字節(jié)大小,它占個位,雖然一個房子它可能什么都么有但是它難道就不是房子了嗎,起碼那塊地還是一個房子,理應有一個位置
#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;
//雖然里面什么都沒有但是這個位置是要在的
cout << &a << endl;
cout << &b << endl;
return 0;
}
沒有成員變量的類對象,需要1byte是為了占位,表示對象存在
二、this指針
作為成員函數(shù)的隱形指針,接收對象地址
#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;
}
雖然兩個對象初始化不同,但是我在調用打印函數(shù)時,實參可是什么都沒傳,都是call同一個地址,為何結果卻不同?
既然類中的成員函數(shù)是放在公共代碼區(qū)的,不在對象總,這個函數(shù)的地址是固定的,
那么為何兩個對象調用它(函數(shù))時所得結果會不一樣(都是call同一個地址)
是因為對象在調用時編譯器隱含的將對象的地址作為實參給傳了過去,而函數(shù)形參隱含用this指針接收 在調用時,默認將對象地址當作實參傳過去
調試程序,然后右擊鼠標,點擊轉到反匯編,查看匯編代碼

這些匯編代碼是在將實參壓棧

可以發(fā)現(xiàn)原本調用成員函數(shù)Init時只是顯式傳了三個實參,但是在底層匯編指令卻壓了四個參數(shù),那是因為將對象的地址作為實參隱含壓棧

在壓棧時,會將對象的地址作為實參壓棧傳給它所調用的成員函數(shù)
在vs下面,對this指針傳遞進行了優(yōu)化,將對象的地址放在寄存器(rcx)中,寄存器(rcx)存this指針的值

Print這里有隱含對象形參指針的,但是不能將其顯式的寫出來
不可修改this指針指向的對象,因為this是被const修飾(相當于day*const this)它的指向對象不可被修改
但是它指向對象的內(nèi)容可以被修改
也可以通過this指針訪問對象成員變量
雖然成員函數(shù)形參this指針不能顯式寫出
但是在成員函數(shù)內(nèi)要訪問對象中成員變量時卻可以顯示寫出

可不可以這樣訪問類的成員變量?
不可這樣直接訪問,就算是類所以成員都是對外開放的,但是類中的成員變量只是聲明了,并沒有將其實例化,相當于房子,只拿著一張圖紙,你就想在現(xiàn)實世界找到對應的房間,抱歉不可能

那么可不可以這樣直接調用類的成員函數(shù)?
這種直接在類中調用它的成員函數(shù),其實是不行的,因為這都沒有定義出對象,編譯器在調用Print函數(shù)時是會隱晦的將對象地址當作實參傳過去,這里連對象都沒有如何調用?
那么有人又會說,那我傳空地址可否?在調用時,對象地址是隱晦的壓棧,并不能顯式的寫出來,也是不行的
#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調用函數(shù)init會對這個函數(shù)解引用嗎?不會,因為這個函數(shù)的地址不在這個對象中,它在公共代碼區(qū) p會作為實參傳給this指針
雖然定義類對象是為空的指針,但是調用類成員初始化函數(shù),并沒有報錯,是因為沒有訪問對象中的成員變量

這樣會發(fā)生錯誤,因為訪問對象中的成員,但是this指針的值為空,對空指針解引用,這樣極其危險的操作
總結
到此這篇關于C++學習進階篇之類大小計算和this指針的文章就介紹到這了,更多相關C++類大小計算和this指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言實現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實例詳解
這篇文章主要介紹了C語言實現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實例詳解的相關資料,這里對實現(xiàn)該函數(shù)進行了代碼實現(xiàn),需要的朋友可以參考下2017-01-01

