C++之類和物件基礎認知
類是什麼呢?
類我們可以認為是C語言中結構體的升級版本,因為C語言中的結構體只能定義變數,而在類中我們還可以定義函式。
為什麼要出現類呢?
首先我們先說一下C++和C語言的一些區別
C語言是面向過程的,關注的是過程,分析出求解問題的步驟,通過函式呼叫逐步解決問題。
C++是基於面向物件的,關注的是物件,將一件事情拆分成不同的物件,靠物件之間的互動完成
比如我們養了一堆小狗,我們就應該把他們的資訊記錄下來
struct Dog
{
int age;//年齡
int weight;//體重
char varity[10];//種類
};
但是現實中我們的一堆小狗不僅僅有資訊要記錄,他們還有技能比如說都會跑都會叫,這個變數就無法幫助我們記錄了
這時候就需要用到我們的成員函式,C++中定義類的關鍵字預設為class,當然也可以用struct.後面我們再談他們的區別。
class Dog
{
void run();
void bark();
int age;//年齡
int weight;//體重
char varity[10];//種類
};
class是關鍵字, Dog是類名 ,下面的變數叫做資料成員,而兩個函式就叫做成員函式。
我們養的一堆狗就可以統稱為一類,而其中單獨的一隻就可以叫做一個物件。
下面我們說說類的訪問限定符
類有三個訪問限定符
1.public:公有
2.protected:保護
3.private:私有
我們養的每一隻狗都是一個物件,他們的種類年齡體重都是不同的這是他們自己的,是他們私有的。 但他們卻同時可以叫和跑
此時叫和跑兩個成員函式就是大家都有的就叫做公有的。
關於訪問限定符的說明
1.public修飾的成員再類外可以被直接訪問。
2.protected和private則不能再類外被直接訪問
3.訪問許可權作用域從該訪問限定符出現的位置開始到下一個訪問限定符出現為止。
4.這點就來解釋struct和class在C++的區別
在C++中struct既可以用來定義結構體也可以用來定義類但是他與class不同的是
class定義的類如果不加訪問限定符預設為私有的,而struct預設為公有的。
類的作用域:
類的定義也就定義了一個新的作用域,所有的成員都在這個作用域裡,在類外定義成員需要使用::作用域解析符指明成員屬於哪個型別。
類的例項化:
用類建立物件的過程就被成為類的例項化
class Dog
{
public:
void run();
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
return 0;
}
這就是例項化出了兩個物件d1和d2。
例項化之後成員變數是獨立的成員函式是共享的之前我們也提過了。
需要注意的是
類只是一個模型,我們建立一個類,系統並不會分配實際的記憶體空間去儲存他
一個類可以例項化多個物件,例項化出來的物件才會佔用實際的物理空間,儲存成員變數
我們可以這樣理解,我們要造一堆坦克,首先要設計出一個坦克的圖紙或者說是模型,然後才能根據我們設計的圖紙和模型進行建造,
我們可以把圖紙理解成一個類。建成的一個個坦克車就是我們通過圖紙這個類例項化出來的物件
如何計算類的大小呢?
其實類的大小就是該類中成員變數之和,但是要注意記憶體對齊。
類的記憶體對齊和結構體的記憶體對齊規則一致
1.第一個成員在偏移量為0的地址處
2.其他成員變數要對齊到某個數字的整數倍的地址處
對其數=編譯器預設的一個對齊數與該成員大小的較小值
VS中預設是8,gcc中預設是4
3.結構體總大小為:最大對齊數整數倍(意思就是如果按照規則算出來結構體大小為15但最大對齊數為4那麼結構體實際總大小則為4的倍數,就會按16計算)。
4.如果出現巢狀,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數的整數倍(包括巢狀的結構體)。
那麼問什麼要存在記憶體對齊呢?
可以提高記憶體的訪問效率,記憶體按整數倍位置訪問。
this指標:
this指標就是C++編譯器給每個成員函式增加了一個隱藏的指標引數,讓改指標指向當前物件,在函式中變數所有操作都是通過this指標去訪問,只不過我們看不見操作而已,編譯器會幫我們完成這個操作。
為什麼要有this指標呢?
先看看我們之前的一份程式碼
class Dog
{
public:
void run()
{
cout<<_age<<"-"<<_weight<<endl;
}
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
d1.run();
d2.run();
return 0;
}
我們通過Dog類例項化出兩個物件d1和d2。
然後我們分別呼叫d1.run()和d2.run()
函式中沒有關於物件進行區分,那我們呼叫d1.run()。為什麼不會輸出d2的資訊呢?
就是因為this指標的存在,其實內部是
class Dog
{
public:
void run(Dog* this)
{
cout <<this-> _age << "-" <<this-> _weight << endl;
}
void bark();
private:
int _age;
int _weight;
char varity[10];
};
int main()
{
Dog d1;
Dog d2;
d1.run();
d2.run();
return 0;
}
this指標的特性: 1.this的型別是類型別*const
2.只能在成員函式內部使用
3.時刻指向當前物件,不屬於物件的一部分,不會影響sizeof的結果
4.this指標成員函式第一個隱含的指標形參,一般由編譯器通過exc暫存器自動傳遞,不需要使用者進行傳遞。
這樣我們就對類和物件有了基本的認識。