在派生类中的私有虚函数

7

可能是重复的问题:
C++:覆盖公共/私有继承

(Possible Duplicate:C++:覆盖公共/私有继承)
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 derived;
b->doSomething();    // Calls the derived class function even though that is private

问题:

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

现在如果我将继承访问限定符从public更改为protected/private,就会出现编译错误:

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

注意:我了解继承访问说明符的概念。因此,在第二种情况下,由于它是派生的私有/受保护的,它是不可访问的。但我想知道第一个问题的答案。非常感谢您的任何帮助。
3个回答

7
在第一种情况下,访问检查是在调用所通过的静态类型上完成的(与常规过程相同)。*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() 是私有的了。


7

访问控制是在编译时实现的,而多态性(包括使用虚函数)是运行时特性。


1
我认为他想知道访问限定符为什么会这样工作,而不是知道错误的来源。 - Hossein

0

私有函数意味着它们应该对外部世界和派生类隐藏。虽然您正在覆盖父类的DoSomething访问说明符并将其设置为private,但您正在实例化一个基类;因此,在第一种情况下,您可以调用base的DoSomething,因为它是公共的。如果您想阻止人们从您的派生类派生,则可以使用此场景。

在第二种情况下,private访问说明符导致基类的成员不会暴露给派生类的用户,这有效地使得派生类无用。


1
原帖很清楚地说“它能够调用派生类函数”。你关于“你可以调用基类的DoSomething,因为它是公共的”的猜测是错误的,基于给定的例子,也不是对问题1的答案。 - StahlRat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接