2013-10-18 38 views
1

我對以下代碼產生的輸出感到驚訝(g++ 4.4.7)。使用後期綁定從非私有上下文中調用私有方法

class A { 
public: 
    virtual void f() {std::cout << "A::f()" << std::endl;} 
}; 

class B : public A { 
private: 
    // Automatically virtual, because of base class 
    void f() {std::cout << "B::f()" << std::endl;} 
}; 

int main(int argc, const char *argv[]) 
{ 
    A *pB = new B(); 
    pB->f(); 
    return 0; 
} 

輸出是

B::f() 

我知道,因爲後期綁定編譯器不能在這裏發出一個錯誤,但我們爲什麼可以調用私有方法從非私有上下文?

原理是什麼?

回答

2

n3376 11.5.1

爲虛擬功能的訪問規則(第11)是由它的聲明來確定,並且不被 影響對於後來覆蓋它的功能的規則。

11.5.2

訪問被使用用於表示的量, 成員函數被調用的對象的表達式的類型在調用點檢查。成員函數在 中定義的成員函數(上面示例中的D)的訪問一般是未知的。

+0

正確的答案是我正在尋找!無法在標準中找到它。謝謝。 –

1

訪問說明符僅用於編譯目的。程序分配內的任何內存都可以被可執行文件的任何部分訪問;有在運行時沒有公共/私人理念

後期綁定功能運行時間因此對於運行時間

+0

你能指出引用的來源(或刪除引用塊,如果這些是你自己的話:))? –

0

其實我試圖執行該代碼稍加修改就沒有任何公共和私有觀念指定基地
私人部分的類虛函數,我從編譯器中得到錯誤。因爲在編譯時
時間首先控制去基類函數但是它是在私有段中定義的,所以
編譯器拋出錯誤。無論何時聲明派生類的對象都採用基類的引用
。在編譯時,控制首先轉到基類,每個類 創建它自己的虛擬表,然後運行時指針對象調用派生類 函數,並且不管它在哪裏聲明爲private或public,如前所述。

class A { 
     virtual void f() {std::cout << "A::f()" << std::endl;} 
    }; 

class B : public A { 
    private: 
    // Automatically virtual, because of base class 
     void f() {std::cout << "B::f()" << std::endl;} 
}; 

int main(int argc, const char *argv[]) 
{ 
    A *pB = new B(); 
    pB->f(); 
return 0; 
} 
+0

我們通過基類指針調用f(),這就是爲什麼控件首先進入基類。 – Subhajit