設計這種類型的目的是將它當做一個內建(built-in)類型一樣被使用。在聲明處賦值是必須的,以保證如下可能:建立真正的本地對象(genuinely local objects)(比如那些在棧中而不是在堆中分配的對象),或者使某些簡單操作被適當地inline化。對于那些支持內建的復合類型的語言來說,要獲得它們提供的效率,真正的本地對象和inline化都是必要的。
為什么成員函數默認不是virtual的?
因為很多類并不是被設計作為基類的。例如復數類。
而且,一個包含虛擬函數的類的對象,要占用更多的空間以實現虛擬函數調用機制——往往是每個對象占用一個字(word)。這個額外的字是非?捎^的,而且在涉及和其它語言的數據的兼容性時,可能導致麻煩(例如C或Fortran語言)。
要了解更多的設計原理,請參見《C++語言的設計和演變》(The Design and Evolution of C++)。
為什么析構函數默認不是virtual的?
因為很多類并不是被設計作為基類的。只有類在行為上是它的派生類的接口時(這些派生類往往在堆中分配,通過指針或引用來訪問),虛擬函數才有意義。
那么什么時候才應該將析構函數定義為虛擬呢?當類至少擁有一個虛擬函數時。擁有虛擬函數意味著一個類是派生類的接口,在這種情況下,一個派生類的對象可能通過一個基類指針來銷毀。例如:
class Base {
// ...
virtual ~Base();
};
class Derived : public Base {
// ...
~Derived();
};
void f()
{
Base* p = new Derived;
delete p; // 虛擬析構函數保證~Derived函數被調用
}
如果基類的析構函數不是虛擬的,那么派生類的析構函數將不會被調用——這可能產生糟糕的結果,例如派生類的資源不會被釋放。
延伸閱讀
文章來源于領測軟件測試網 http://www.kjueaiud.com/