2012-11-29 64 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

相关问题