1

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()

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

理由是什么?

4

3 回答 3

2

n3376 11.5.1

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

11.5.2

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

于 2013-10-18T11:43:22.640 回答
1

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

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

于 2013-10-18T11:50:12.733 回答
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;
}
于 2013-10-18T12:11:26.503 回答