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

Using late binding to call a private method from a non private context

本文关键字:上下文 调用 有方法 绑定      更新时间:2023-10-16

我对下面的代码段(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()

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

理由是什么?

n3376 11.5.1

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

11.5.2

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

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

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

实际上,

我尝试执行此代码,只需进行少量修改即可指定基础
私人部分中的类虚拟函数,我从编译器收到错误。因为在编译
中 时间优先控件转到基类函数,但它在私有部分中定义,因此
编译器抛出错误。每当声明派生类的对象时,都会将
基类的引用。在编译时,控制首先转到基类,每个类 创建自己的虚拟表,然后在运行时指针对象调用派生类 功能,正如我之前所说,它被宣布为私有或公共无关紧要。

   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;
}