1.派生類中定義虛函數必須與基類中的虛函數的函數簽名一模一樣即函數名相同 參數列表相同 返回值類型相同缺一不可
否則會被認為是重載而不是虛函數。如果基類中返回值是個基類指針,派生類中返回派生類指針是允許的這是個特例
2.只有類的成員函數才能聲明為虛函數,這是因為虛函數僅僅適用於有著繼承關係的類對象
3.靜態成員函數,是所有同一類對象共有的 不受限於某個對象,不可作為虛函數
4.一個類對象的靜態和動態類型是相同的,實現動態特性必須使用基類類型的指針變量或引用 使該
指針指向該基類的不同派生類的對象,並通過該指針指向虛函數表才能實現動態的多態性
5.內聯函數每個對象一個拷貝,無映射關係,不能作為虛函數
6.析構函數可以定義為虛函數,構造函數不可以定義為虛函數,因為在調用構造函數對象還沒有完成實例化,
在基類中及其派生類中都動態分配內存空間時,必須把析構函數定義為虛函數,實現撤銷對象的多態性
7.多態性要付出一定的代價,因為函數的調用要通過虛表間接調用。
============華麗的分割線===================
補充說明小例子:
class A
{
public:
void FuncA()
{
printf( "FuncA called\\n" );
}
virtual void FuncB()
{
printf( "FuncB called\\n" );
}
};
class B : public A
{
public:
void FuncA()
{
A::FuncA();
printf( "FuncAB called\\n" );
}
virtual void FuncB()
{
printf( "FuncBB called\\n" );
}
};
void main( void )
{
B b;
A *pa;
pa = &b;
A *pa2 = new A;
pa->FuncA(); ( 3)
pa->FuncB(); ( 4)
pa2->FuncA(); ( 5)
pa2->FuncB();
delete pa2;
}
父類指針指向子類實例對象,調用普通重寫方法時會調用父類中的方法
在調用被子類重寫的虛函數時會調用子類的方法。也就是隻有虛函數才有動態性。
閱讀更多 coder人生 的文章