2013-05-31 91 views
3

在下面的程序中,基類A中的函數'f'對於派生類B的對象是隱藏的。但是當我通過const A * d調用函數f B的指針對象,來自基類的函數f被調用。如果我刪除了指針的const說明符(即A * d),則派生類中的函數'f'被調用。我的查詢如何常量在這裏有所作爲?謝謝你的幫助。通過指向const的指針調用虛擬函數基類

#include <iostream> 

class A 
{ 
public: 
    virtual void f(int n) { std::cout << "A::f\n"; } 
    virtual ~A() { } 

    void f(int n) const { std::cout << "A::f const\n"; } 
}; 

class B 
    : public A 
{ 
public: 
    void f(int n) { std::cout << "B::f\n"; } 

    void f(int n) const { std::cout << "B::f const\n"; } 
}; 

int main() 
{ 
    const A a; 
    B b; 
    A &c = b; 
    const A *d = &b; 

    c.f(1); 
    d->f(1); 


    return 0; 
} 

輸出(與常量A * d): B ::˚F A ::˚F常量

輸出(與A * d) B ::˚F B ::˚F

回答

4

要調用的函數的簽名是根據指針的靜態類型的指針確定的。然後在運行時選擇正確的簽名覆蓋。

換句話說,如果你有這樣的:

const A *d; 
d->f(1); 

那麼f中搜索在const A。所以它找到了非虛擬的void f(int) const

但是,如果你有這樣的:

A *e; 
e->f(1); 

那麼f在非const A搜索。所以它找到virtual void f(int),然後(在運行時)委託給最終覆蓋void B::f(int)

EDIT

這從上成員函數選擇規則如下。當通過const路徑(指針或參考)進行訪問時,只有const成員函數適用。當通過非const路徑訪問時,會考慮非const函數。只有沒有指針(或引用)才隱式轉換爲指向const的指針(或引用),然後才考慮const成員函數。