重寫、重定義和繼承完全是兩個概念,比如析構函式:能被派生類重寫,來實現多型,可以方便的用指向基類的指標釋放派生類的物件,不能被繼承,因為舉個例子,派生類和基類有不同的成員,如果基類的預設析構函式是從基類繼承的話,那麼派生類在析構時就有記憶體空間不能被釋放的問題存在了,所以析構函式是不能被繼承的。
「繼承」是一整套的機制,是對類而言的。對乙個成員函式說能否被繼承,容易引起語言上的概念混淆(至少各人的理解不同)。所以,這裡就列舉析構函式與普通函式的異同,至於能不能「繼承」,請先回答什麼叫乙個成員函式的繼承,然後可以對照這裡的內容得出答案。
首先,析構函式和普通函式一樣,可以被顯示地呼叫。如類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++提供如此與普通函式、與建構函式有一些相同、又都有些不同的析構函式「繼承」規則,就是為了最大限度地賦予程式設計師使用和控制物件析構機制的能力,這是其它許多語言所無法做到的。
重寫 過載和重定義
函式過載 1 必須在乙個類中 2 子類無法過載父類的函式,父類同名的函式將被名稱覆蓋 不管引數相不相同 3 過載是在編譯期間根據引數型別和個數決定函式呼叫 函式重寫 1 必須發生於父類和子類之間 2 父類和子類之間必須有相同的函式原型 3 使用virtual關鍵字之後可以產生多型 如果不使用virt...
過載重寫和重定義
include using namespace std 重寫 過載 重定義 重寫發生在2個類之間 過載必須在乙個類之間 重寫分為2類 1 虛函式重寫 將發生多型 2 非虛函式重寫 重定義 class parent virtual void func virtual void func int i v...
過載重寫和重定義
過載重寫與重定義 一 過載和重寫理解 1 函式過載 必須在同乙個類中進行 子類無法過載父類的函式,父類同名函式將被名稱覆蓋 過載是在編譯期間根據引數型別和個數決定函式呼叫 2 函式重寫 必須發生在父類和子類之間 並且父類與子類中的函式必須有完全相同的原型 使用virtual宣告之後能夠產生多型 如果...