C++ 派生类中的私有虚函数
可能重复:C++ 派生类中的私有虚函数,c++,C++,可能重复: 问题: 它能够调用派生类函数,即使它是私有的。这怎么可能 现在,如果将继承访问说明符从public更改为protected/private,则会出现编译错误: 'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible 注意:我知道继承访问说明符的概念。所以在第二种情况下,由于它是派生的私有/受保护的,所以它是不可访问的。但我想知道第一个问题的答案。任何输入都将受到高度赞赏。访
问题:
'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible
注意:我知道继承访问说明符的概念。所以在第二种情况下,由于它是派生的私有/受保护的,所以它是不可访问的。但我想知道第一个问题的答案。任何输入都将受到高度赞赏。访问控制是在编译时而不是运行时实现的,而多态性(包括使用虚拟函数)是运行时特性 在第一种情况下,对调用所通过的静态类型进行访问检查(通常是这样)。
*b
的静态类型是base
,在这种情况下doSomething()
是public
C++03 11.6“访问虚拟函数”说明:
虚拟函数的访问规则(第11条)由
它的声明和不受以下函数的规则影响
后来,它覆盖了它。[示例:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK:B::f()is public,
// D::f() is invoked
pd->f(); //error:D::f()is private
}
-[结束示例]
在调用点使用用于表示调用成员函数的对象的表达式类型(上例中的B*)检查访问。成员函数在其定义的类中的访问权限(上例中为D)通常是未知的
请特别记住,“在定义成员函数的类中(在上面的示例中为D)成员函数的访问通常是未知的”。通常,在您的示例中,
b->doSomething()调用code>时,编译器可能根本不知道派生的
(或子类
),更不用说对派生的::doSomething()
的访问是否是私有的。私有函数意味着对外部世界和派生类隐藏。尽管您正在重写父级DoSomething的访问说明符并使其私有,但您正在实例化一个基类;因此,在第一种情况下,您可以将base的DoSomething称为public。如果您想阻止人们从派生类派生,可以使用此场景
在第二种情况下,private
访问说明符使基的成员不向派生类的用户公开,这实际上使派生类变得无用。我想他想知道访问说明符为什么会这样工作,而不是知道错误的来源。OP说得很清楚,它能够调用派生类函数。基于给定的示例,您关于您可以称为base的DoSomething(因为它是公开的)的猜测是错误的,并且不是问题1的答案。
'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK:B::f()is public,
// D::f() is invoked
pd->f(); //error:D::f()is private
}