在c/c++中,經常會發生資料型別轉換,例如整型資料可以賦值給浮點型變數,在賦值之前,先把整型資料轉換為浮點型;反過來,浮點型資料也可以賦值給整型變數。
資料型別轉換的前提是,編譯器知道如何對資料進行取捨。例如:
int a = 10.9輸出結果為 10,編譯器會將小數部分直接丟掉(不是四捨五入)。再如:;printf(
"%d\n
", a);
float b = 10輸出結果為 10.000000,編譯器會自動新增小數部分。;printf(
"%f\n
", b);
類也是一種資料型別,也可以發生資料型別轉換。不過這種轉換只有在基類和派生類之間才有意義。
由於派生類包含從基類繼承的成員,因此可以將派生類的物件賦值給基類物件,如下所示:
classa是b的基類,a、b 分別是它們的物件,所以可以將 b 賦值給 a,然後通過 a 來訪問成員變數 m。a;class b: public
a;a a;
b b;
a =b;
a.m = 2;
實際上,物件之間的賦值是成員變數的賦值,成員函式不存在賦值問題。在賦值時,會捨棄派生類自己的成員,也就是」大材小用「,如下圖所示:
可以發現,即使將派生類物件賦值給基類物件,基類物件也不會包含派生類的成員,所以依然不同通過基類物件來訪問派生類的成員。對於上面的例子,a.m 是正確的,但 a.n 就是錯誤的,因為 a 不包含成員 n。
這種轉換關係是不可逆的,只能用派生類物件給基類物件賦值,而不能用基類物件給派生類物件賦值。理由是很顯然的,基類不包含派生類的成員,無法對派生類的成員變數賦值。同理,同一基類的不同派生類物件之間也不能賦值。
要理解這個問題,還得從賦值的本質入手。賦值實際上是向記憶體填充資料,當資料較多時很好處理,捨棄即可;上例中,a=b 時,成員 n 是多餘的,會被直接丟掉,所以不會發生賦值錯誤。但當資料較少時,問題就很棘手,編譯器不知道如何填充剩下的記憶體;上例中,b= a 時,編譯器不知道該如何給變數 n 賦值,所以會發生錯誤。
請看下面乙個完整的例子:
#include using本例中,將 b 物件賦值給 a 物件,等價於 a.n = b.n,賦值完成後 a.n 的值為 2,然後呼叫 a.display() 函式,輸出結果就是」class a: n=2「。將 c 物件賦值給 a 物件也是同樣的道理。namespace
std;
class
a
void display()
};class b: public
a
void display()
};class c: public
a
void display()
};int
main()
這個例子很好的說明了:基類物件和派生類物件之間的賦值僅僅是對應的成員變數的賦值,不會影響成員函式,不會影響 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 語言中,乙個派生類可以從乙個基類派生,也...