2012-11-29 121 views
6

Possible Duplicate:
C++: overriding public\private inheritance私人虛函數在派生類中

class base { 
public: 
    virtual void doSomething() = 0; 
}; 

class derived : public base { 
private: // <-- Note this is private 

    virtual void doSomething() 
    { cout << "Derived fn" << endl; } 
}; 

現在,如果我做了以下內容:

base *b = new child; 
b->doSomething(); // Calls the derived class function even though that is private 

問:

  1. 它能夠調用派生類的函數,即使它是私人的。這怎麼可能?

現在,如果我改變繼承訪問說明符從公衆保護/私有,我得到一個編譯錯誤:

'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible 

注:我知道的繼承訪問說明的概念。所以在第二種情況下,它是由private/protected派生的,因此無法訪問。但我想知道第一個問題的答案。任何意見將不勝感激。

回答

6

訪問控制是在編譯時而不是運行時實現的,而多態性(包括使用虛函數)是一個運行時功能。

+0

我想他想知道訪問說明符爲什麼這樣工作,而不知道錯誤的來源是什麼。 – Hossein

6

在第一種情況下,訪問檢查是在完成調用的靜態類型上完成的(因爲它總是完成)。 *b的靜態類型爲base,在這種情況下doSomething()public

C++ 03 11.6「訪問虛擬功能」雲:

The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [Example:

class B { 
public: 
    virtual int f(); 
}; 

class D : public B { 
private: 
    int f(); 
}; 

void f() 
{ 
    D d; 
    B* pb = &d; 
    D* pd = &d; 

    pb->f(); //OK:B::f()is public, 
      // D::f() is invoked 
    pd->f(); //error:D::f()is private 
} 

—end example]

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

記住尤其是「成員函數的在類訪問在其被定義(在上述的例子d )一般不知道「。一般來說,在調用b->doSomething();的示例中,編譯器可能根本不知道derived(或child),更不用說對derived::doSomething()的訪問是否是私有的。

0

私有函數意味着從外部世界和派生類隱藏。儘管您重寫父級的DoSomething的訪問說明符並將其設置爲私有,但您正在實例化一個基類;所以在第一種情況下,你可以調用base的DoSomething,因爲它是公開的。如果您想阻止從派生類派生的人員,可以使用此方案。

在第二種情況下,private訪問說明符會導致基本成員不會暴露給派生類的用戶,這有效地使派生類無用。

+0

OP說得很清楚**它能夠調用派生類函數**。你對**的猜測可以稱爲基礎的DoSomething,因爲它是公開的**根據給定的例子是錯誤的,並且不是問題1的答案。 – StahlRat

相關問題