C 學習21 基類和派生類的賦值

2022-07-16 10:09:08 字數 2323 閱讀 4856

在c/c++中,經常會發生資料型別轉換,例如整型資料可以賦值給浮點型變數,在賦值之前,先把整型資料轉換為浮點型;反過來,浮點型資料也可以賦值給整型變數。

資料型別轉換的前提是,編譯器知道如何對資料進行取捨。例如:

int a = 10.9

;printf(

"%d\n

", a);

輸出結果為 10,編譯器會將小數部分直接丟掉(不是四捨五入)。再如:

float b = 10

;printf(

"%f\n

", b);

輸出結果為 10.000000,編譯器會自動新增小數部分。

類也是一種資料型別,也可以發生資料型別轉換。不過這種轉換只有在基類和派生類之間才有意義。

由於派生類包含從基類繼承的成員,因此可以將派生類的物件賦值給基類物件,如下所示:

class

a;class b: public

a;a a;

b b;

a =b;

a.m = 2;

a是b的基類,a、b 分別是它們的物件,所以可以將 b 賦值給 a,然後通過 a 來訪問成員變數 m。

實際上,物件之間的賦值是成員變數的賦值,成員函式不存在賦值問題。在賦值時,會捨棄派生類自己的成員,也就是」大材小用「,如下圖所示:

可以發現,即使將派生類物件賦值給基類物件,基類物件也不會包含派生類的成員,所以依然不同通過基類物件來訪問派生類的成員。對於上面的例子,a.m 是正確的,但 a.n 就是錯誤的,因為 a 不包含成員 n。

這種轉換關係是不可逆的,只能用派生類物件給基類物件賦值,而不能用基類物件給派生類物件賦值。理由是很顯然的,基類不包含派生類的成員,無法對派生類的成員變數賦值。同理,同一基類的不同派生類物件之間也不能賦值。

要理解這個問題,還得從賦值的本質入手。賦值實際上是向記憶體填充資料,當資料較多時很好處理,捨棄即可;上例中,a=b 時,成員 n 是多餘的,會被直接丟掉,所以不會發生賦值錯誤。但當資料較少時,問題就很棘手,編譯器不知道如何填充剩下的記憶體;上例中,b= a 時,編譯器不知道該如何給變數 n 賦值,所以會發生錯誤。

請看下面乙個完整的例子:

#include using

namespace

std;

class

a

void display()

};class b: public

a

void display()

};class c: public

a

void display()

};int

main()

本例中,將 b 物件賦值給 a 物件,等價於 a.n = b.n,賦值完成後 a.n 的值為 2,然後呼叫 a.display() 函式,輸出結果就是」class a: n=2「。將 c 物件賦值給 a 物件也是同樣的道理。

這個例子很好的說明了:基類物件和派生類物件之間的賦值僅僅是對應的成員變數的賦值,不會影響成員函式,不會影響 this 指標。

總結:可以通過派生類物件訪問派生類的成員,但無論如何,也不能通過基類物件訪問派生類成員。

對上例 main 函式中的**做如下更改:

a *p = new a(1

);p->display();

p = new b(2

);p->n = 100

;p->display();

p = new c(3

);p->display();

輸出結果:

class a: n=1

class a: n=100

class a: n=3

本例定義了乙個指標,使它指向不同的物件。與上例不同的是,本例中並沒有發生物件的賦值,僅僅是改變了指標的指向。

輸出結果的第2行與上例不同,這是為什麼呢?

在**第3行中,將 p 指向 b 類的物件,隱式指標 this 也隨之改變,指向 b 類的物件,所以 p->n 和 this->n 訪問的都是 b 類物件的成員變數,輸出結果顯然是」n=100「。

細心讀者可能已經發現,雖然 this 指向了 b 類物件,但是 p->display() 依然呼叫 a 類的成員函式。這是因為,成員變數和成員函式不在同乙個記憶體區域,系統通過 this 指標來訪問成員變數,但是卻不通過它來訪問成員函式。

系統通過物件的型別來訪問成員函式。例如 p 的型別是 a,那麼不管 p 指向哪個物件,都訪問 a 類的成員函式。

C 派生類與基類的賦值

class a class b a void main 可以把派生類賦值給基類。我們知道賦值,是呼叫了類的賦值運算子。所以當派生類給基類賦值時,呼叫了基類的複製運算子函式,該函式的引數是基類物件的const 引用,那麼 a b,實際就是用基類引用派生類,然後將派生類中基類部分賦值給對應的基類成員。而...

C 基類和派生類

本講討論基類和派生類的基本概念。通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。在c 語言中,乙個派生類可以從乙個基類派生,也可...

C 基類和派生類

本講討論基類和派生類的基本概念。通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。在 c 語言中,乙個派生類可以從乙個基類派生,也...