多态
公有繼承派生類對象使用基類的方法,如果希望同一種方法派生類和基類的行為是不同的,也即方法的行為取決于調用該方法的對象,這種行為稱為多态。
- 基類使用虛方法(此時派生類自動成為虛方法,可以指出也可以不指出)。
- 基類不使用虛方法,在派生類直接重定義該方法。
聲明為virtual
如果不将函數聲明為virtual,程式将根據引用類型或者指針類型選擇方法。如果聲明為virtual,程式将根據引用或者指針指向對象本身的類型來選擇方法。
舉例來說
基類中方法和析構函數均不聲明為virtual的情況
#include <iostream>
#include <memory>
using namespace std;
class Base
{
public:
Base() { cout << "created Base\n"; }
void function() { cout << "this is Base's function" << endl; }
~Base(){cout << "this is Base's destroy" << endl;}
};
class Derived : public Base
{
public:
Derived(){ cout << "created derived" << endl;}
void function(){cout << "this is Derived's function" << endl;}
~Derived(){cout << "this is Derived's destroy" << endl;}
};
int main()
{
Base* ptr = new Derived;
// std::unique_ptr<Base> ptr(new Derived);
ptr->function();
delete ptr; // delete 語句的根本含義在于調用其析構函數,并釋放記憶體
return 0;
}
輸出
created Base
created derived 可以看出構造函數不受影響,被執行了
this is Base's function 雖然對象是派生類,但是由于指針是指向基類的,是以執行了基類的方法
this is Base's destroy 雖然對象是派生類,但由于指針是指向基類的,是以隻執行了基類的析構函數,是以該對象未被完全釋放。
基類中方法與析構函數均聲明為virtual的情況
#include <iostream>
#include <memory>
using namespace std;
class Base
{
public:
Base() { cout << "created Base\n"; }
virtual void function() { cout << "this is Base's function" << endl; }
virtual ~Base(){cout << "this is Base's destroy" << endl;}
};
class Derived : public Base
{
public:
Derived(){ cout << "created derived" << endl;}
void function(){cout << "this is Derived's function" << endl;}
~Derived(){cout << "this is Derived's destroy" << endl;}
};
int main()
{
Base* ptr = new Derived;
// std::unique_ptr<Base> ptr(new Derived);
ptr->function();
delete ptr; // delete 語句的根本含義在于調用其析構函數,并釋放記憶體
return 0;
}
輸出
created Base
created derived
this is Derived's function 執行的是派生類的方法,雖然指針指向的是基類
this is Derived's destroy 析構函數也被正确調用了,
this is Base's destroy
其他說明
若方法是通過對象(而不是指針或者引用調用的),則沒有虛方法特性!