Tables | 關鍵字 |
---|---|
1.什麼是面向對象 | |
2.類 | 概念,特點 |
3.類的大小 | 爲什麼要內存對齊?內存對齊的計算?空類的計算 |
4.類的4個默認成員函數的詳細使用 |
1.什麼是面向對象
官方定義:
面向對象是一種思想,是基於面向過程而言的。就是說面向對象是將功能等通過對象來實現,將功能封裝進對象之中,讓對象去實現具體的細節;這種思想是將數據作爲第一位,而方法或者說是算法作爲其次,這是對數據一種優化,操作起來更加的方便,簡化了過程。面向對象有三大特徵:封裝性、繼承性、多態性,
官方定義太過抽象,含糊,爲適應大多數場景,所以難以理解。下面來針對C++理解什麼是面向對象。
來看下面舉例:
“分析下面需求實現的方案
我的午餐 - 西紅柿雞蛋打滷麪
方案一:
實現的大致步驟
1>購買西紅柿,雞蛋和麪粉
2>打滷
3>和麪,擀麪條,煮麪
4>午餐成功做好了
“方案一的特點
強調的是做 西紅柿雞蛋打滷麪 這件事情的具體的實現步驟,強調每一個步驟都是”我”自己做的,”我”是絕對的執行者.
方案二:
1.實現大致步驟
1>使用手機下載”美團外賣”
2>搜索西紅柿雞蛋打滷麪,下單
3>午餐成功送到
“方案二的特點
強調的”美團外賣”在整個事件中起到的作用,”美團外賣”是這個事件的主角.”我”是一個指揮者.
總結:面向對象和麪向過程
1.面向過程:對於一個問題.強調事情解決的每一個步驟都是當事人自己親自實現,這種解決問題的思路叫面向過程,就像方案一自己動手煮麪的過程
2.面向對象:對於一個問題.強調事情解決過程通過當事人找到一個專門解決這類問題的專家來幫助自己解決問題.當事人扮演”指揮者”,這種解決問題的思路叫面向對象,就像方案二用美團外賣下單打滷麪的過程。
3.官方定義裏的對象就是指類的實例化。(類的實例化就好比蓋一棟大樓,首先會在設計圖上設計好這棟大樓的具體框架,然後 工程師就會按照設計圖紙來建造大樓。類就好比圖紙,它包含了對象的大體框架,對象實例化就好比按照圖紙,產生一個實際的大樓一樣。
)
“面向對象和麪向過程的側重點
1.面向過程和麪向對象只是解決問題的不同方案,不同思路.
2.面向過程:強調把控實現的細節.
3.面向對象:找專家解決問題,這些專家很多都在框架中已經存在,可以直接引用.如果沒有提供,可以自己創造,之後還可以複用—> 高效和複用.
特點:封裝性 ,繼承,多態
先來了解封裝特性:
1:將數據和方法封裝在類裏
2:使用狀態限定符,想給你看的數據設置成公有,不想給你看的設置成私有。對數據和方法進行限定訪問。實現高內聚,低耦合。
2.類的基礎知識
C++ 類定義
定義一個類,本質上是定義一個數據類型的藍圖。這實際上並沒有定義任何數據,但它定義了類的名稱意味着什麼,也就是說,它定義了類的對象包括了什麼,以及可以在這個對象上執行哪些操作。
類的結構:由成員變量和成員函數組成。成員變量指定對象中應該包含的數據,成員函數指定對象可以執行那些操作。
類定義是以關鍵字 class /struct開頭,後跟類的名稱。類的主體是包含在一對花括號中。類定義後必須跟着一個分號或一個聲明列表。
類的簡單定義:
先來看一個簡單類定義的格式:
類的定位:
本文討論的類也是C++數據結構中自定義類型的一種。由於這是C++種特有的一種數據類型,所以特地拿出來討論,前面幾種數據類型和C語言使用相同(C++兼容C),這裏不再討論。
類的限定符
class類默認成員爲私有,struct默認成員爲公有。
類的作用域
- 每個類都定義了自己的作用域,類的成員(成員函數/成員變量)都在類的這個作用域內,成員函數內可任意訪問成員變量和其它成員
函數。 - 對象可以通過. 直接訪問公有成員,指向對象的指針通過->也可以直接訪問對象的公有成員。
- 在類體外定義成員,需要使用:: 作用域解析符指明成員屬於哪個類域。
成員函數的聲明定義
1.在類域以內定義成員函數
class Person
{
public:
void Display()
{
cout<<_name<<"-"<<_age<<"-"<<_id<<endl;
}
public:
char* _name;
int _age;
int _id;
};
2 在類外定義成員函數,需要加上作用域
class Person
{
public:
void Display()
public:
char* _name;
int _age;
int _id;
};
void Person::Display()
{
cout<<_name<<"-"<<_age<<"-"<<_id<<endl;
}
類實例化對象
1.類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類並沒有分配實際的內存空間來存儲它。就好比生活中的雪糕模子,模子只有一個,且不佔用任何食材。通過這個莫子可以產生多個雪糕,類也是同理。一個類可以產生多個對象。
2.一個類可以實例化出多個對象,實例化出的對象佔用實際的物理空間存儲類成員變量。。就好比生活中的雪糕模子,模子只有一個,且不佔用任何食材。通過這個莫子可以產生多個雪糕。類也是同理。一個類可以產生多個對象。
類的存儲
1.由於類存儲時,成員函數在公共區域,所以計算sizeof(類名)時,成員函數的大小不算在內。
2.所以每個對象的大小爲類中所有成員變量的大小之和,當然這裏也遵循內存對齊原則。
成員函數存在 進程虛擬地址空間的代碼區。
運用實例
#include<iostream>
using namespace std;
class Person
{
public:
void Display()
{
cout<<_name<<"-"<<_age<<"-"<<_id<<endl;
}
public:
char* _name;
int _age;
int _id;
};
int main()
{
// .形式訪問
Person p;
p._name="jack";
p._age=20;
p._id=123456;
p.Display();
//指針形式訪問
Person *point=&p;
point->_name="Rose";
point->_age=21;
point->_id=654321;
point->Display();
return 0;
}
運行結果
[zyc@localhost lession_class]$ ./a.out
jack-20-123456
Rose-21-654321
常見報錯:
1.成員變量私有,卻在類外訪問
class.cpp:18: error: ‘char* Person::_name’ is private
2.類定義完畢不加 ; 結尾
class.cpp:10: note: (perhaps a semicolon is missing after the definition of ‘Person’)
類的大小計算
首先來看實例:
#include<iostream>
using namespace std;
class A
{
char a;
int b;
short c;
};
class B
{
short c;
char a;
int b;
};
int main()
{
cout<<"sizeof(A)="<<sizeof(A)<<endl;
cout<<"sizeof(B)="<<sizeof(B)<<endl;
return 0;
}
運行結果
[zyc@localhost lession_class]$ ./a.out
sizeof(A)=12
sizeof(B)=8
那麼問題來了:這些變量只是換了一下順序,算出來的結果卻不一樣。
這裏就要用內存對齊來解釋這個原因了。
首先來看內存對齊規則。(先學會用再探究原因)
結構體內存對其規則:
1.第一個成員在與結構體變量偏移量爲0的地址處。
2.其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。
對齊數=編譯器默認的一個對齊數與該成員大小的較小值。
VS中默認的值爲8
gcc中的默認值爲4
3.結構體總大小爲最大對齊數(每個成員變量除了第一個成員都有一個對齊數)的整數倍。
4.如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體
的對齊數)的整數倍。
按照規則,我們來看剛纔的例子。
變量A的存儲(在linux下,默認對齊數:4)
同理,B的存儲如下
從以上分析可得,
sizeof(A)=12
sizeof(B)=8
就不難理解了。經過內存對齊後,結構體的空間反而增大了。
**內存對齊原因?
1 內存訪問不是一次訪問一次一個字節,太浪費時間,某,到底一次訪問多個字節(這個由硬件總線決定)。這裏假設一次訪問四字節。
空類的計算**