菜鳥學習歷程 27 物件導向程式設計(1)

2021-08-14 14:05:39 字數 4227 閱讀 9689

什麼叫做面向過程程式設計?

通俗的來說,這種程式設計風格如同從上到下,從左到右。首先,要考慮遵循的步驟,然後考慮如何表現這些資料。

那麼什麼又是物件導向程式設計呢?

從使用者的角度出發考慮物件,描述物件所需的資料以及描述使用者與資料進行互動所需要的操作。完成對介面的描述後,需要確定如何實現介面和資料儲存。

特點:封裝、繼承、多型

封裝:資料進行隱藏,把不想讓外部使用的資料狀態隱藏起來;

繼承:實現**復用;

多型:實現功能的擴充套件。

抽象和類

抽象:將問題的本質抽取出來,並根據特徵來描述解決方案;

類:類是一種將抽象轉化為使用者定義型別的c++工具,他將資料的表示和操縱的方法組合成乙個整潔的包;

下面,舉乙個圓的例子進行說明:

#include 

using

namespace

std;

const

int pi = 3.14;

class circle

void prints()

;int main()

說明:這個圓類中包含了兩個成員,半徑(m_r)和面積(m_s),這兩個成員就代表了圓的屬性。圓類中,還有兩個方法,乙個求取面積,乙個用來列印,都是對資料的操縱,可以看出,這些屬性和方法都是在這個class circle中,也就是說,類中包含了物件的屬性、包含了對物件的操縱的函式。像這樣的形式,物件導向程式設計。

不難發現,這種類的形式與結構體十分相像,其實在c++的內部,類也的確是由結構體進行實現的。那麼這兩者的區別在哪呢?

1.在c++中,結構體內部允許設定訪問許可權,預設訪問許可權是公有,而類的預設訪問許可權是私有

2.定義乙個結構體,可以直接用「=」進行初始化,但類只能使用建構函式進行初始化;

類的內部成員(變數和函式)訪問許可權

三種:public、private、protected

public:公有屬性,類的內部和外部都可以訪問;

protected:保護屬性,類的內部可以訪問,外部不可訪問;

private:私有屬性,類的內部和外部都不可以訪問。

建構函式和析構函式

建構函式:類的物件使用建構函式完成初始化

1.函式名與類名相同;

2.沒有返回值;

3.不需要手動呼叫(一般情況下),系統自動呼叫。

析構函式:**資源

1.函式名與類名相同,函式名前加~;

2.沒有返回值;

3.**物件資源,當物件被釋放時,系統自動呼叫。

注意:

建構函式可以過載,析構函式不可過載

建構函式又分為無參構造、有參構造。

還是以上面的圓類進行說明:

#include 

using

namespace

std;

const

int pi = 3.14;

class circle

circle(int r)

~circle()

double calus()

void prints()

;int main()

那麼建構函式被呼叫的情形有哪些?

1.使用括號()

circle c1; 呼叫無參構造

cirlcle c2(2);呼叫乙個引數的建構函式

2.用「=」號

circle c1 = 4; ==> circle c1(4)

circle c2 = (2, 3);==> circle c2(3) ,其後的(2, 3)其實是乙個逗號表示式

3.手動呼叫

circle c1 = circle(); ==> circle c1

circle c2 = circle(2);==> circle c2(2)

拷貝建構函式:用乙個物件對另外乙個物件進行初始化時,系統會自動呼叫;

呼叫的情形如下:

1.

circle c1(1, 2);

circle c2(c1); ==> circle c2(circle c1);

2.circle c1(1, 2);

circle c2 = c1; ⇒ circle c2(c1);

3.circle c1(1, 2);

circle c2 = circle(c1);

注意:circle c1(1, 2);

circle c2;

c2 = c1; ??? 會呼叫拷貝建構函式嗎?

答案是否定的,上述的形式只是賦值,並不是初始化,呼叫拷貝建構函式必須是初始化的時候。

4.當乙個函式的形參是乙個物件時,會呼叫拷貝建構函式

//circle obj = c1; 因此,在引數傳遞時,要傳物件的引用或者指標

void func(circle obj)

int main()

5.物件作為函式的返回值時

circle func()

在物件作為函式返回值時,會涉及到乙個匿名物件的處理,分為三種情況:

1.返回值不被接受時

2.用新物件去接收時

3.用乙個已經存在的物件去接收時

預設建構函式如果類中沒有定義拷貝建構函式,編譯器會預設新增乙個拷貝建構函式,這個拷貝建構函式進行的是變數「值」的複製,不會複製堆上的空間。==>淺拷貝

自己編寫拷貝建構函式,實現堆上空間的複製。==>深拷貝

下面舉個例子說明淺拷貝與深拷貝的區別:

#include 

using

namespace

std;

class student

~student()

void print()

private:

int m_age;

char *m_name;

};int main()

//上述**,在執行時會有段錯誤發生,錯誤原因在於堆上的位址二次釋放,下面解釋一下為什麼使用預設拷貝建構函式會出現這種情況。

當定義物件 stu1 時,會在堆上開闢 20 位元組的空間用來存放名字,當使用 stu1 初始化 stu2 時,預設拷貝建構函式只是執行簡單的「值」的複製,所以 stu2 的名字與 stu1 指向的是同一塊位址,因此在析構的時候,會對 0x1000 這塊位址釋放兩次,於是便發生了段錯誤。

那麼為了避免這種情況的發生,需要自己寫乙個拷貝建構函式。

#include 

using

namespace

std;

class student

~student()

student(const student &obj) //自己編寫的拷貝建構函式

void print()

private:

int m_age;

char *m_name;

};int main()

分析一下,為什麼這樣就不會出錯了呢?

當定義物件 stu1 時,會在堆上開闢 20 位元組的空間(0x1000)用來存放名字,當使用 stu1 初始化 stu2 時,會呼叫自己編寫的拷貝建構函式,在函式體內,我們對 m_name 也開闢了20位元組的空間(0x2000),這樣兩個物件的 m_name就指向不同的位址,析構時也不會出現對同一塊位址重複釋放的錯誤。

27 物件導向程式設計

物件導向程式設計 物件導向程式設計 object oriented programming,簡稱oop,是一種程式設計方法。物件導向面向過程區別 完成自我介紹功能,面向過程完成功能 stu a stu b stu c def stu info stu 自我介紹 for key,value in st...

Python學習 27 物件導向程式設計4

這一節我們來繼續介紹物件導向程式設計。涉及到的內容有property屬性和運算子的過載。1.property屬性 之前的物件導向程式設計中,我們介紹了兩種訪問屬性的方式。第一種是物件名.屬性名,這種直接訪問屬性的方式 第二種是使用get和set方法訪問屬性。第二種方式 的靈活性比第一種要高,並且第二...

Python學習 27 物件導向程式設計4

這一節我們來繼續介紹物件導向程式設計。涉及到的內容有property屬性和運算子的過載。1.property屬性 之前的物件導向程式設計中,我們介紹了兩種訪問屬性的方式。第一種是物件名.屬性名,這種直接訪問屬性的方式 第二種是使用get和set方法訪問屬性。第二種方式 的靈活性比第一種要高,並且第二...