我对以下代码(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()
我知道由于后期绑定,编译器不能在这里发出错误,但为什么我们可以从非私有上下文调用私有方法呢?
理由是什么?
答案 0 :(得分:2)
11.5.2虚函数的访问规则(第11条)由其声明确定,不受影响 稍后覆盖它的函数的规则。
使用用于表示对象的表达式的类型在调用点检查访问 调用成员函数。成员函数在类中的访问权限 它的定义(上例中的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;
}