派生类中的私有虚函数

use*_*047 6 c++

可能重复:
C++:重写public\private继承

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

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

  virtual void doSomething()
  { cout << "Derived fn" << endl; }
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我执行以下操作:

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

题:

  1. 它可以调用派生类函数,即使它是私有的.这怎么可能?

现在,如果我将继承访问说明符从public更改为protected/private,我会收到编译错误:

'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible
Run Code Online (Sandbox Code Playgroud)

注意:我知道继承访问说明符的概念.所以在第二种情况下,因为它是派生私有/受保护的,所以它是不可访问的.但我想知道第一个问题的答案.任何输入都将受到高度赞赏.

小智 6

访问控制在编译时实现,而不是在运行时实现,而多态(包括使用虚函数)是运行时功能.


Mic*_*urr 6

在第一种情况下,访问检查在完成调用的静态类型上完成(因为它总是完成).静态类型*bbase,在这种情况下doSomething()public.

C++ 03 11.6"访问虚函数"说:

虚函数的访问规则(第11节)由其声明确定,并且不受稍后覆盖它的函数规则的影响.[例:

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
}
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

使用表达式的类型在调用点检查访问,该表达式用于表示调用成员函数的对象(上例中的B*).成员函数在其定义的类中的访问(上例中的D)通常是未知的.

请特别注意"成员函数在其定义的类中的访问权限(上例中的D)通常是未知的".通常,在您的示例中b->doSomething();调用的位置,编译器可能根本不了解derived(或child),更不用说访问是否derived::doSomething()是私有的.