2012-04-18 131 views
0

據我所知,friend沒有被繼承。我有課Parent Person Child。父母和人是彼此的朋友。家長有以下PROTECTED功能...C++朋友繼承

class Person 
{ 
    friend class Parent; 
    public: 
     Parent * parent; 
} 

class Parent 
{ 
    friend class Person; 
    protected: 
     virtual void Answer() = 0; 
} 

class Child : public Parent 
{ 
    void Answer() 
    { 
     std::cout << "Child!" << endl; 
    } 
} 

我的問題是,如果友誼不繼承,我怎麼能有以下...? (Person有一個指向父)

Person person; 
Child child; 
person.parent->Answer(); 

爲什麼這個孩子的輸出!和它不拋出試圖訪問一個虛函數時運行時錯誤?

我很困惑孩子的功能是如何實現的,程序沒有在運行時出錯,因爲我預計它會嘗試調用父的虛擬應答功能。

+0

你有什麼遺產嗎?即你的子類的定義中的'class Child:public Parent'? – 2012-04-18 17:51:35

+0

您不會在Q. – 2012-04-18 17:52:00

+6

中看到的'Child'上調用任何函數,而不是描述您的代碼,請發佈一個微不足道(但完整)的代碼片段。那樣,我們都可以清楚你的繼承/友誼關係在回答時。 – 2012-04-18 17:52:09

回答

3

您沒有訪問Child::Answer但是Parent::Answer這裏,沒關係,因爲Parent是你的朋友。事實上,這是一個Child對象並不重要。但是,在運行時真正調用哪個方法很重要。由於Parent::Answervirtual,與Child::Answer覆蓋就意味着誰不知道什麼是Child是,仍然會調用Child::Answer即使Child通過Parent引用或指針訪問主叫方(有,在解決了相應的函數間接層運行)。

你甚至可以連實施Child後來鏈接針對此.o文件,遞給它一個Child例如,僞裝成Parent&Parent*之前編譯這個。 Person將永遠不會有機會,即使知道有一些東西叫Child,但仍然能夠「找到」正確的實施。這是動態綁定的力量。

+0

好吧,清除它,謝謝! – Joshua 2012-04-18 18:10:19

+0

什麼孩子對象?該調用是對Person的父對象。 – juanchopanza 2012-04-18 18:15:20

+0

@juanchopanza:是的,我在OP添加聲明+三個類的實現之前回答。這個問題具體詢問'Child :: Answer'如何從'Person'上下文中調用。 – bitmask 2012-04-18 18:22:53