类的概念、成员函数的定义方式、类的访问控制和封装、类的大小、this指针
文章目錄
- 類的概念
- struct
- class
- class和struct的區別是什么呢?
 
- 類中成員函數的兩種定義方式
- 聲明和定義都在類中
- 聲明和定義分離
 
- 類的訪問控制和封裝
- 類的封裝特性
 
- 類的大小
- 結構體內存對齊規則
- 類的存儲方式
 
- this指針
類的概念
在C++中,類可以說是最重要的東西,因為C++一開始的定位就是c with class,也正是因為引入了類,才讓c++從c的面向過程思想轉變為面向對象的思想,關注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成。
C++有兩種能夠創建類的方法
struct
第一種是struct,也就是從C繼承而來的,在C語言中,struct可以用來創建結構體,但是結構體中只能保存變量,而不能保存函數,在C++中,struct不僅可以用來創建類,還保留了C語言中結構體的用法
struct Date {void PrintDate(){cout << _year << '-' << _month << '-' << _day << endl;}int _year;int _month;int _day; };class
class是C++中定義類的關鍵字,他的用法和struct類似。
在類中,類的元素被稱為類的成員,類中的數據被稱為成員變量或者類的屬性,類中的函數被稱為類的方法或者成員函數
class Date {void PrintDate(){cout << _year << '-' << _month << '-' << _day << endl;}int _year;int _month;int _day; };class和struct的區別是什么呢?
類中成員函數的兩種定義方式
聲明和定義都在類中
如果成員函數在類內部定義,則其是隱式的inline函數。
class Date {void PrintDate(){cout << _year << '-' << _month << '-' << _day << endl;}int _year;int _month;int _day; };聲明和定義分離
在類內聲明,在類外定義,這樣能讓類更加簡潔,不那么臃腫,通常都是使用這種方式。
class Date {void PrintDate();int _year;int _month;int _day; };//需要通過作用域運算符指定這個方法屬于Date類 void Date::PrintDate() {cout << _year << '-' << _month << '-' << _day << endl; }類的訪問控制和封裝
訪問限定符有三種,分別是public,private,protected
 
類的封裝特性
封裝:將數據和操作數據的方法進行有機結合,隱藏對象的屬性和實現細節,僅對外公開接口來和對象進行 交互。
封裝本質上是一種管理:我們如何管理兵馬俑呢?如果什么都不管,兵馬俑可能會被隨意破壞。那么我們首先建了一座房子把兵馬俑給封裝起來。但是我們目的并不是全封裝起來,不讓別人看。所以我們開放了售票通道,可以通過買票突破封裝、在合理的監管機制下進去參觀。類也是一樣,我們將類數據和方法都封裝一下。不想給別人肆意修改,我們使用protected/private把成員封裝起來。同時開放一些共有的成員函數對成員合理的訪問機制。所以封裝本質是一種管理。
一般對于對象的屬性,我們不希望別人對它進行修改,所以會用private將其封裝,但是我們又需要給別人提供獲取它的接口,所以會對方法和接口給與public屬性。
類的大小
class Date { public:void PrintDate();private:char a;int _year;int _month;int _day; };我們可以看到,類中有成員函數,有成員變量,那么類的大小是如何計算的呢?
int main() {Date d;cout << sizeof(d) << endl; }
 這里用sizeof查看大小,發現只有成員變量的大小(三個int類型一個char類型,3*4+1=13,這里的16是因為內存對齊偏移了3個字節),而沒有成員函數的大小
結構體內存對齊規則
注意:對齊數 = 編譯器默認的一個對齊數 與 該成員大小 兩者中的較小值。(如int大小為4,VS中默認的對齊數為8,取4)
類的存儲方式
為什么會只保存了成員變量呢?這里就要引申出類的存儲方式。
對于上面的類,如果我們將類實例化為多個對象,實際上這些對象不同的地方只有它的屬性,它們調用的方法都是完全相同的, 為了不重復保存這些代碼,C++只保存了屬性,而將方法放到了公共的代碼段中,來避免了空間的浪費。
 
 同時,如果一個類中什么都沒有,編譯器會給這個類一個字節,來唯一標識這個類。
 
 總結:類的大小就是成員變量之和(需要考慮內存對齊)
this指針
void Date::PrintDate() {cout << _year << '-' << _month << '-' << _day << endl; }對于類中的成員函數,我們并沒有將對象的屬性傳給他,那么他是如何能夠獲取這些屬性的呢?
C++編譯器給每個“非靜態的成員函數“增加了一個隱藏的指針參數(this指針),讓該指針指向當前對象(函數運行時調用該函數的對象),在函數體中所有對成員變量的操作,都是通過該指針去訪問。只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成。
其實類的成員函數中隱含了一個this指針,所以在編譯器處理的時候,上面的代碼等價于
void Date::PrintDate(Date * const this) {cout << this->_year << '-' << this->_month << '-' << this->_day << endl; }- 這個this指針的類型是類類型 * const this,之所以是頂層const的原因是因為this指針唯一指向對象地址。
- this指針只能在成員函數中使用
- this指針本質上其實是一個成員函數的形參,是對象調用成員函數時,將對象地址作為實參傳遞給this形參。所以對象中不存儲this指針,this指針存在寄存器中。
- this指針是成員函數第一個隱含的指針形參,一般情況由編譯器通過ecx寄存器自動傳遞,不需要用戶傳遞,
同時,如果this指針為空時,成員函數使用到了this指針,則會崩潰,如果沒使用,則正常運行
總結
以上是生活随笔為你收集整理的类的概念、成员函数的定义方式、类的访问控制和封装、类的大小、this指针的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Qt中出现段错误的原因分析
- 下一篇: SpaceVim 语言模块 python
