目錄
虛函數介紹
虛函數、覆蓋和重載區別
虛函數介紹
C++的虛函數是多態性的表現
1.構造函數不能為虛函數 |
2.子類繼承時虛函數仍為虛函數 |
3.虛函數類外實現時,不需要加virtual |
4.有虛函數的類,析構函數一定要寫成虛函數(否則可能會造成內存泄漏) |
5.純虛函數不能實例化,子類必須實現父類虛函數,否則也不能實例化 |
class A
{
public:virtual A(){} //報錯:“A”:“inline”是構造函數的唯一合法存儲類
}
class A
{
public:A(){ cout << "A() " << endl; }virtual void print(void) { cout << "A::print() " << endl; }
};class B : public A
{
public:B() { cout << "B() " << endl;}void print(void) { cout << " B::print() " << endl; }//雖然沒有寫virtual,但繼承來自A,所以仍然為virtual。但強烈建議寫上virtual
};class C : public B
{
public:C() { cout << "C() " << endl; }virtual void print(void);
}void C::print(void) //類外實現函數體時不需要加 virtual
{cout << "C::print()!" << endl;
}int main(void)
{A *a = new C;a->print(); //打印 C::print()!return 0;
}
class A
{
public:A(){}virtual void print(void) = 0;
};class B : public A
{
public:B(){}
//此處沒有對print進行實現
};int main()
{
// A a; //報錯,“A”: 無法實例化抽象類
// B b; //報錯,“B”: 無法實例化抽象類return 0;
}
class A
{
public:A() { cout << "A()" << endl;}virtual void print(void) { cout << "A::print()!" << endl; }~A() { cout << "~A()" << endl; } //此處析構函數未聲明為virtual
};class B : public A
{
public:B() { cout << "B()" << endl; }virtual void print(void) { cout << "B::print()" << endl; }~B() { cout << "~B()" << endl; }
};int main(void)
{A *a = new B;a->printf();delete a; //注意看下面執行結果打印return 0;
}
執行結果如下,只執行了類A的析構函數,new出來的B的析構沒有執行,內存泄漏
?
當A的析構函數聲明為virtual,則先執行B的析構函數,在執行A的析構函數
虛函數、覆蓋和重載區別
虛函數:父類某成員函數必須用virtual聲明,子類重寫的函數定義完全與父類相同(參數類型,參數個數和返回值),發生在父類和子類之間,父類可以調用子類的函數
覆蓋:父類成員函數不用virtual聲明,子類成員函數名稱與父類相同(參數類型,參數個數和返回值可以不同),子類則完全覆蓋父類所有相同名稱的函數(即子類不能訪問父類相同函數名稱的函數)
重載:同一類的類成員函數之間,成員函數名稱相同,但成員函數的參數類型、參數個數必須有至少一項不同