本章目錄
- 1.面向程序和面向物件的初步認識
- 2.類的引入
- 3.類的定義
- 4.類的訪問限定符及封裝
- 4.1訪問限定符
- 4.1封裝
- 5.類的作用域
- 6.類的實體化
- 7.類物件型別
- 7.1如何計算類物件的大小
- 7.2結構體記憶體對齊規則
- 8.this指標
- 8.1 this指標詳解
1.面向程序和面向物件的初步認識
C語言是面向程序的,關注的是程序,分析出求解的步驟,通過函式呼叫逐步解決問題,
C++是基于面向物件的,關注的是物件,將一事件拆分成不同的物件,靠物件之間的互動完成,
2.類的引入
C語言中,結構體只能定義變數,在C++中,結構體內不僅可以定義變數,也可以定義函式,
struct Student
{
void SetStudentInfo(const char* name, const char* gender, int age)
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void PrintStudentInfo()
{
cout << _name << " " << _gender << " " << _age << endl;
}
char _name[20];
char _gender[3];
int _age;
};
int main()
{
Student s;
s.SetStudentInfo("pater", "男", 18);
return 0;
}
上面結構體的定義,在C++中更喜歡用class來代替
3.類的定義
class className
{
//類體:由成員函式和成員變陣列成
//一定注意后面的分號
};
class為定義類的關鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結束時后面分號,
類中的元素稱為類的成員:類的資料稱為類的屬性或者成員變數;類中的函式稱為類的方法或者成員函式,
類的兩種定義方式:
- 宣告和定義全部放在類體中,需要注意:成員函式如果在類中定義,編譯器可能會將其行內函式處理
//人
class Person
{
public:
//顯示基本資訊
void showlnfo()
{
cout << _name << "-" << _sex << "-" << _age << endl;
}
public:
char* _name;//姓名
char* _sex;//姓名
int _age;//年齡
};
- 宣告放在.h檔案中,類的定義放在.cpp檔案中

一般情況下,更期望采用第二種方式,
4.類的訪問限定符及封裝
4.1訪問限定符
C++實作封裝的方式:用類將物件的屬性與方法結合在一起,讓物件更加完善,通過訪問權限選擇性的將其介面提供給外部的用戶使用,

【訪問限定符說明】
- Public修飾的成員在類外可以直接被訪問,
- protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)
- 訪問權作用域從該訪問限定符出現的位置開始直到下一個訪問限定符出現時為止
- class的默認訪問權限為private,struct為public因為struct要兼容C
注意:訪問限定符指在編譯時有用,當資料映射到記憶體后,沒有任何訪問限定符上的區別
【面試題】
問題:C++需要兼容C語言,所以C++中struct可以當成結構體去使用,另外C++中struct還可以用來定義類,和class定義類是一樣的,區別是struct的成員默認訪問方式是public , class是struct的成員默認方式是private.
4.1封裝
【面試題】面向物件的三大特征:封裝、繼承、多型
在類和物件階段,我們只研究類的封裝性,那么什么是封裝呢?
封裝:將資料和操作資料的方法進行有機結合,隱藏物件的屬性和現實細節,進對外公開介面來和物件進行互動
封裝本質上是一種管理:類資料和類方法不想給別人看到,我們使用protected和private把成員封裝起來,開放一些共有的成員函式隊成員合理的訪問,所以封裝本質是一種管理,
5.類的作用域
類定義一個新的作用域,類的所有成員都在類的作用域中,在類體外定義成員,需要使用::作用域決議符指明成員屬于哪個類域,
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
//這里需要制定PrintPersonInfo是屬于Person這個類域
void Person::PrintPersonInfo()
{
cout << _name << " "<<_gender << " " << _age << endl;
}
6.類的實體化
用型別別創建物件的程序,稱為類的實體化
- 類只是一個模型一樣的東西,限定了類有哪些成員,定義出了一個類并沒有分配實際的記憶體空間來存盤它,
- 一個類可以實體化出對個物件,實體化出的物件占用實際的物理空間,存盤類成員變數
- 做個比方,類實體化出物件就像現實中使用建筑設計圖建在出房子,類就像是設計圖,只設計出需要什么東西,但是并沒有物體的建筑存在,同樣類也只是設計,實體化出的物件才能存盤資料,占用物理空空間,

7.類物件型別
7.1如何計算類物件的大小
一個類的大小,實際就是該類中成員變數之和,當然也要進行記憶體對齊,注意空類的大小,空類比較特殊,編譯器給了空類一個位元組來唯一標識這個類,
// 類中既有成員變數,又有成員函式
class A1 {
public:
void f1(){}
private:
int _a;
};
// 類中僅有成員函式
class A2 {
public:
void f2() {}
};
// 類中什么都沒有---空類
class A3
{};
sizeof(A1) : 4 sizeof(A2) :1 sizeof(A3) : 1
7.2結構體記憶體對齊規則
- 第一個成員在與結構體偏移量為0的地址處
- 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處,
注意:對其數=編譯器默認的一個對齊數與該成員大小的較小值 - 結構體總大小為:最大對其數(所有變數型別最大者與默認對其引數取小)的整數倍
- 如果嵌套了結構體的情況,嵌套結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍
8.this指標
我們先定義一個日期類
class Date
{
public :
void Display ()
{
cout <<_year<< "-" <<_month << "-"<< _day <<endl;
}
void SetDate(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};
int main()
{
Date d1, d2;
d1.SetDate(2018,5,1);
d2.SetDate(2018,7,1);
d1.Display();
d2.Display();
return 0;
}
對于上述類,有這樣一個問題
Date類中有SetDate與Display兩個成員函式,函式體中沒有關于不同物件的區分,那當s1呼叫SetDate函式時,該函式是如何知道應該設定s1物件,而不是設定s2物件呢?C++中通過引入this指標解決該問題,即:C++編譯器給每個“非靜態的成員函式“增加了一個隱藏的指標參
數,讓該指標指向當前物件(函式運行時呼叫該函式的物件),在函式體中所有成員變數的操作,都是通過該指標去訪問,只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成,
8.1 this指標詳解
- this指標的型別:型別別* const
- 只能在“成員函式”的內部使用
- this指標本質上其實是一個成員函式的形參,是物件呼叫成員函式時,將物件地址作為實參傳遞給this形參,所以物件中不存盤this指標,
- this指標是成員函式第一個隱含的指標形參,一般情況由編譯器通過ecx暫存器自動傳遞,不需要用戶傳遞

【面試題】 - this指標存在哪里?
- this指標可以為空嗎?
- 的方法
class A
{
public:
void PrintA()
{
cout<<_a<<endl;//會崩潰,_a沒有實體化
}
void Show()
{
cout<<"Show()"<<endl;
}
private:
int _a;
};
int main()
{
Date* p = NULL;
p->PrintA();
p->Show();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272339.html
標籤:其他
