使用后期绑定从非私有上下文调用私有方法

时间:2013-10-18 11:38:42

标签: c++ inheritance class-visibility

我对以下代码(g++ 4.4.7)产生的输出感到惊讶。

class A {
public:
    virtual void f() {std::cout << "A::f()" << std::endl;}
};

class B : public A {
private:
    // Automatically virtual, because of base class
    void f() {std::cout << "B::f()" << std::endl;}
};

int main(int argc, const char *argv[])
{
    A *pB = new B();
    pB->f();
    return 0;
}

输出

B::f()

我知道由于后期绑定,编译器不能在这里发出错误,但为什么我们可以从非私有上下文调用私有方法呢?

理由是什么?

3 个答案:

答案 0 :(得分:2)

n3376 11.5.1

虚函数的访问规则(第11条)由其声明确定,不受影响 稍后覆盖它的函数的规则。

11.5.2

使用用于表示对象的表达式的类型在调用点检查访问 调用成员函数。成员函数在类中的访问权限 它的定义(上例中的D)通常是未知的。

答案 1 :(得分:1)

访问说明符仅用于编译目的。程序的分配中的任何内存都可以被可执行文件的任何部分访问;在运行时没有公共/私人概念

后期绑定函数是运行时,因此运行时没有公共和私有概念

答案 2 :(得分:0)

实际上我已经尝试执行此代码而几乎没有修改来指定基础
 私有部分中的类虚函数,我从编译器得到错误。因为在编译中  时间第一个控制转到基类函数但它在私有部分定义所以
 编译器抛出错误。每当你声明派生类的一个对象时,取  基类的引用。在编译时控制首先进入基类和每个类  制作自己的虚拟表,然后运行时指针对象调用派生类  正如我先前所说的那样,功能并没有被宣布私有或公开的事项。

   class A {
         virtual void f() {std::cout << "A::f()" << std::endl;}
  };

class B : public A {
   private:
     // Automatically virtual, because of base class
      void f() {std::cout << "B::f()" << std::endl;}
 };

int main(int argc, const char *argv[])
 {
  A *pB = new B();
   pB->f();
 return 0;
}