关于c ++:派生类中的私有虚函数


Private virtual function in derived class

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
C++: overriding public\private inheritance

1
2
3
4
5
6
7
8
9
10
11
class base {
public:
  virtual void doSomething() = 0;
};

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

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

现在,如果我的以下的:

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

问题:

  • 它是能够调用的函数衍生类虽然它是私人的。这是如何可能的?
  • 现在,如果我改变继承的访问说明符从公共到私人保护/编译错误:I get a

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

    注:我知道的概念specifiers继承的访问。第二个案例的操作系统在它的源的保护,它的inaccessible。但我想先了解到问题的答案。任何输入将是非常理解的。


    在第一种情况下,对调用所通过的静态类型执行访问检查(总是这样)。*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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class B {
    public:
        virtual int f();
    };

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

    void f()
    {
        D d;
        B* pb = &amp;d;
        D* pd = &amp;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();时,编译器可能根本不了解derivedchild,更不用说访问derived::doSomething()是私有的。


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


    私有函数应该隐藏在外部世界和派生类中。虽然您要覆盖父级dosometing的访问说明符并使其成为私有的,但您正在实例化一个基类;因此在第一种情况下,您可以将基的dosometing称为公共的。如果您希望停止从派生类派生人员,则可以使用此方案。

    在第二种情况下,private访问说明符使基成员不向派生类的用户公开,这实际上使派生类无用。