1. 程式人生 > >關於重寫和重定義

關於重寫和重定義

重寫、重定義和繼承完全是兩個概念,比如解構函式:能被派生類重寫,來實現多型,可以方便的用指向基類的指標釋放派生類的物件,不能被繼承,因為舉個例子,派生類和基類有不同的成員,如果基類的預設解構函式是從基類繼承的話,那麼派生類在析構時就有記憶體空間不能被釋放的問題存在了,所以解構函式是不能被繼承的。

“繼承”是一整套的機制,是對類而言的。對一個成員函式說能否被繼承,容易引起語言上的概念混淆(至少各人的理解不同)。所以,這裡就列舉解構函式與普通函式的異同,至於能不能“繼承”,請先回答什麼叫一個成員函式的繼承,然後可以對照這裡的內容得出答案。
首先,解構函式和普通函式一樣,可以被顯示地呼叫。如類D公有繼承類B,它們的解構函式也都是公有的。那麼下述程式碼是合法的:
B b;
b.~B();
D d;
d.B::~B();
從中可以看出,對B的物件而言,~B與其他函式在呼叫並不差異,而對D的物件而言,B::~B與其他函式也沒有差異。由此可見,繼承類的物件呼叫基類的解構函式,與呼叫其他基類的函式規則一樣。但是注意了,這裡的呼叫只是它由使用者顯示寫出的函式體,而不包括在物件銷燬時由編譯器插入的其他操作。

其次,子類不能覆蓋(Override)父類的解構函式,這是和普通函式的區別。D中不能再命名~B了。

第三,涉及多型的特殊規則:對一個類層次而言,雖然~B和~D是不同名的函式,但是在多型意義上是同一個函式。因此,virtual ~B意味指向D物件的B指標(或引用)在析構時將呼叫~D。所有的函式中,這是唯一的特例。這是解構函式的特殊性與多型機制結合的產物。

最後,說一下解構函式的特殊性。正如大家所知道了,解構函式會在物件銷燬時被隱式呼叫。並且,執行完使用者編寫的程式碼部分後,它還會依次呼叫資料成員和基類的解構函式(以與構造相反的順序)。在這一點上,它和建構函式一樣特殊。

綜上,子類物件可以顯式呼叫的(如果稱之為“繼承”的話),只有由類設計者顯式編寫的父類解構函式的函式體而已,而不是真正只有編譯器可以呼叫的整個解構函式!C++的這個特性,提供程式設計師隨時顯式清理物件資料的能力,而同時又不威脅預設的析構語義。同時,即使是函式體,也只能被呼叫,不能被覆蓋。相反,多型則是作用在整個解構函式上的,而非函式體上。C++提供如此與普通函式、與建構函式有一些相同、又都有些不同的解構函式“繼承”規則,就是為了最大限度地賦予程式設計師使用和控制物件析構機制的能力,這是其它許多語言所無法做到的。