1. 程式人生 > >c++父類指標指向子類物件

c++父類指標指向子類物件

c++父類指標指向子類物件

 

父類子類指標函式呼叫注意事項
1,如果以一個基礎類指標指向一個衍生類物件(派生類物件),那麼經由該指標只能訪問基礎類定義的函式(靜態聯翩)
2,如果以一個衍生類指標指向一個基礎類物件,必須先做強制轉型動作(explicit cast),這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾。(一般不會這麼去定義)
3,如果基礎類和衍生類定義了相同名稱的成員函式,那麼通過物件指標呼叫成員函式時,到底呼叫那個函式要根據指標的原型來確定,而不是根據指標實際指向的物件型別確定。

 


虛擬函式就是為了對“如果你以一個基礎類指標指向一個衍生類物件,那麼通過該指標,你只能訪問基礎類定義的成員函式”這條規則反其道而行之的設計。
如果你預期衍生類由可能重新定義一個成員函式,那麼你就把它定義成虛擬函式( virtual )。
polymorphism就是讓處理基礎類別物件的程式程式碼能夠通透的繼續適當地處理衍生類物件。
純虛擬函式:
virtual void myfunc ( ) =0;
純虛擬函式不許定義其具體動作,它的存在只是為了在衍生類鐘被重新定義。只要是擁有純虛擬函式的類,就是抽象類,它們是不能夠被例項化的(只能被繼承)。如果一個繼承類沒有改寫父類中的純虛擬函式,那麼他也是抽象類,也不能被例項化。
抽象類不能被例項化,不過我們可以擁有指向抽象類的指標,以便於操縱各個衍生類。
虛擬函式衍生下去仍然是虛擬函式,而且還可以省略掉關鍵字“virtual”。
看個例子:

#include <iostream> 
using namespace std; 
class A 
{ 
public: 
    virtual void foo() 
    { 
        cout << "A's foo()" << endl; 
        bar(); 
    } 
    virtual void bar() 
    { 
        cout << "A's bar()" << endl; 
    } 
}; 
class B: public A 
{ 
public: 
    void foo() 
    { 
        cout << "B's foo()" << endl; 
        A::foo(); 
    } 
    void bar() 
    { 
        cout << "B's bar()" << endl; 
    } 
}; 
int main() 
{ 
    B bobj; 
    A *aptr = &bobj; 
    aptr->foo(); 
    A aobj = *aptr; //轉化為A類物件
    aobj.foo(); 
}


aptr->foo()輸出結果是:
   B's foo()//這個明白,多型性
   A's foo()//這個也明白,執行A::foo();
   B's bar()//雖然呼叫的是這個函式:A::foo(); 但隱式傳入的還是bobj 的地址,所以再次呼叫bar();呼叫時還是會呼叫B的函式, 與虛擬函式指標有關
aobj.foo()輸出結果是:
  A's foo() //這個不是指標,aobj完全是一個A的物件,與多型沒有關係
  A's bar()