Cpp 類和物件

2021-07-10 03:56:34 字數 2729 閱讀 5558

圍繞具體問題對屬性和行為進行有意識的選擇,使複雜的具體問題得到簡化——物件導向的程式設計

1.類的一般形式

class/struct 類名 : 繼承方式 基類, …

~類名 (void)

返回型別 函式名 (形參表) 常屬性 異常說明

資料型別 變數名; // 成員變數

};2.訪問控制限定符

3.成員函式

c++支援三種型別的成員函式,static,nonstatic和virtual,每一種成員函式被呼叫的方式都不同。

3.1nonstatic成員函式

原始的」c-withclass」只支援nonstatic成員函式

c++的設計準則是nonstatic member function至少需要和非成員函式具有相同的執行效率。

編譯器實際上將成員函式內化為非成員函式

在這裡舉乙個例子

假設有類的成員函式

float point3d::magnitude3d()const
轉化為非成員函式的過程大概需要經過以下幾個步驟

1)首先改寫函式原型,將乙個額外的引數安插到成員函式中,用來提供乙個訪問的管道,該額外的引數被稱為this指標

float point3d::magnitude3d(point *const this)const
2)在函式體內對成員資料的訪問通過this指標來完成

float point3d::magnitude3d(point *const

this)const

3) 最後講成員函式重寫為外部的乙個函式,對其函式名進行」mangling」處理,使其稱為獨一無二的標識。

extern magnitude_7ponint3dfv(register point3d *const

this);

tips:mangling處理規則:一般成員名前面加上類名會形成獨一無二的名稱,不過再加上引數列表就會確保名稱這時會是獨一無二的了
這時,成員函式已經轉化好了,而我們的**中通過物件對其進行的每次呼叫,這時也需要有形式上的改變。

obj.magnitude();    ⇒   magnitude_7ponint3dfv(&obj);

ptr->magnitude(); ⇒ magnitude_7ponint3dfv(ptr);

void normalize_7ponint3dfv(register point3d *const

this,point3d &_result)

若normalize函式是乙個虛函式,它會經歷如下的內部轉換

ptr->normalize();   ⇒  (*ptr->vptr[1])(ptr);
其中vptr是由編譯器生成的虛表指標,實際上vptr的名字也會被mangled

而此時如果magnitude函式也是乙個虛函式,則它在normalize函式中的呼叫操作將會被轉化為如下的形式

register

float mag = magnitude(); ⇒ register

float mag = (*this->vptr[2])(this);

這裡要說明一下,由於magnitude在normalize中呼叫,而後者已經已經由虛擬機制resloved(具體的物件已經確定,不必再通過虛指標來進行),所以明確地呼叫ponint3d實體會比較由效率

register

float mag = point3d::magnitude();

magnitude函式宣告為inline函式會更有效率,使用類的域解析符::呼叫乙個virtual函式,其resolved方式會和nonstatic 成員函式一樣。

經由類物件呼叫的虛函式(注意這裡說的並不是基類物件的指標)這種操作應該總是被編譯器對待一般的nonstatic 成員函式一樣地resolved

像是這樣:

point3d obj;

obj.normalize(); => normalize_7point3dfv(&obj);

若normalize函式是乙個靜態成員函式,其呼叫操作會轉化為對乙個nonmember function的呼叫

在引入靜態成員函式之前,c++要求語言要求所有的成員函式都要經過物件來呼叫,但是如果這個成員函式中沒有對成員進行訪問,也就不需要this指標,這樣也就沒有必要通過類的物件來呼叫成員函式。

所以當時出現了這樣一種寫法:

((point3d *)0)->object_count(); 

//函式object_count()函式只是簡單地傳回乙個static data member

上面的呼叫接著會被轉化為object_count((point3d *)0)

把0強制轉化為類的指標,因而也就會提供出了乙個this指標,之所以把0強轉,是因為這個this指標根本用不到!!!

當之後推出了static member function之後,它的最主要的特性就是沒有this指標,所以也就不能直接訪問類中的非靜態成員,也不能被宣告為const,volatile或者virtual,不需要通過類物件來呼叫(並不是說不能!)

C 類和物件 類和物件

c 中物件的型別稱為類,類代表了某一批物件的共性和特徵,類是物件的抽象,而物件是類的具體例項,類是抽象的,不占用記憶體,而物件是具體的,占用 儲存空間,這點很重要,讀者需要牢記。類是使用者自己指定的型別,如果程式中要用到類型別,必須自己根據需要進行宣告,或者使用別人已設計好的類,c 標準本身並不提供...

Cpp 物件模型探索 不能被繼承的類

兩種方法 c 11 final 關鍵字 友元類 虛繼承。栗子class a friend class b class b virtual public a 我們的目的是讓 b 成為乙個不能被繼承的類。分析 由於 b 是 a 的友元,所以即使 a 的建構函式是私有的,b也是可以呼叫的,所以 b 繼承 ...

類模板的 h和 cpp檔案分離

templateclass abc include b.h templatevoid abc setvv t b templatet abc getvv include b.cpp include using namespace std int main abcab ab.setvv 10 cout...