使虚拟函数在C ++中私有

时间:2018-08-05 20:46:15

标签: c++ inheritance virtual-functions private-members

class A 
{
    public:
    virtual void fun() 
    { 
        cout << "A Fun"; 
    }
};

class B:public A
{
    private:
    void fun() 
    { 
        cout << "B Fun"; 
    }
};

class C:public B{};

int main()
{

   //Case1       

   A *ptr = new C();
   ptr->fun();
   /*
         OUTPUT : B Fun
   */

   //Case 2

   B *ptr2 = new C();
   ptr2->fun();
   /*
        ERROR:
        main.cpp: In function ‘int main()’:
        error: ‘virtual void B::fun()’ is private within this context
            ptr2->fun();
                  ^
        note: declared private here
             void fun()
              ^~~ 
   */
   return 0;
}

在情况1中:我可以在B类中调用private fun(),但是为什么在情况2中我不能调用private fun()? 为什么B类中的fun()具有两种不同的行为? 我的意思是说,当我制作A类型的指针时,B类的fun()充当公共函数,但是当我制作B类型的指针时,B类的fun()充当私有函数。

2 个答案:

答案 0 :(得分:1)

  

在情况1中:我可以在B类中调用private fun()[...]

否,您不能可以调用/不能不能调用类private中的B方法。您正在从类public调用A方法,而该方法恰好在子类中被覆盖。

当单元测试私有方法时,这特别有用。您只需使您的类继承自一个伪基类,该基类将感兴趣的方法声明为public和(可能是纯的)virtual

答案 1 :(得分:1)

私有性和公共性是类/结构成员的纯编译时属性。编译器会在编译代码时检查您是否有权访问成员。

所以在您的代码中:

B b;
b.fun(); // Error! B::fun is private in this context!

A& a = static_cast<A&>(b); // `a` is a reference to `b`
a.fun(); // okay, A::fun is public.
         // It just so happen that A::fun is virtual,
         // So the function dispatched at runtime will be B::fun
         // But the compiler has no mean to check this.

只有在函数A::fun是虚拟的时,才确定该函数在运行时的行为。通过覆盖虚拟函数,您必须同意使用A的表达式将被分派到B,而不管B受到什么限制。多态调用A::fun的代码必须适用于任何子类,因为处理基类的代码无法知道派生类。