C++ 要求;“公众”;在自动作用域中使用实例时访问修改器
假设我们有两个类,一个派生自另一个,它只包含一个虚拟非纯方法,如下所示:C++ 要求;“公众”;在自动作用域中使用实例时访问修改器,c++,C++,假设我们有两个类,一个派生自另一个,它只包含一个虚拟非纯方法,如下所示: class Base { public: virtual void method() { cout << "method() called from Base" << endl; } }; class Derived : public Base { public: void method() { cout <<
class Base
{
public:
virtual void method()
{
cout << "method() called from Base" << endl;
}
};
class Derived : public Base
{
public:
void method()
{
cout << "method() called from Derived" << endl;
}
};
int main()
{
Base *instance1 = new Derived();
instance1->method();
Derived derived;
derived.method();
}
类基
{
公众:
虚空法()
{
cout如果你不写public:
,那就好像你写了private:
。如果你问为什么该语言没有自动切换到public:
以获得派生的::方法()
(因为它覆盖了已经是公共的Base::方法()
)。好吧,这是可能的
然而,在阅读代码时,它也会非常令人困惑和误导。作为一名程序员,我更希望我的类定义不会在我背后发生根本性的改变
编译器抛出了一个错误(正如您所发现的),允许我自己进行我认为合适的更改(无论是将Derived::method()
public还是Base::method()
private!),在我看来这是迄今为止最好的结果
相反,如果你问为什么可见性的差异很重要,那么这似乎很明显,不是吗?如果用户通过Base
类接口调用函数,其中method()
是公共的,这会自动调用派生类中的private
函数,这违反了派生类的约定。而且,由于只有名称受这些可见性规则的保护,因此该语言添加了对重写方法的额外检查,以尽可能在c语言中扩展该保护虚拟函数分派的情况。标准中给出了一些非常类似的示例,其中指定了这些内容的规则[class.access.virt]:
1确定虚拟函数的访问规则(第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
}
-[结束示例]
2访问权限为
在调用点使用用于
表示为其调用成员函数的对象(在
中类中成员函数的访问权限
它的定义(上例中的D)通常是未知的
以上回答了您的两个问题:
为什么不编译-根据上面的规则2,使用表达式的类型(即静态而非动态类型)检查访问
这是什么原因?再次,如上所述,通常不知道动态类型是什么。要演示,请考虑:可以将新派生类链接到定义基类的现有代码而不重新编译此代码:显然,它将不可能确定派生的访问控制。(编译时甚至不存在)
请阅读C++中有关访问说明符的更多信息。这将澄清您的疑虑。假设您可以删除<代码>公共<代码> >当您从main函数调用<代码>方法>代码>时,您会想到什么?注意:所有<代码>方法>代码>声明是私有的。@苏美特:这并没有任何帮助,并且“澄清您的怀疑”。毫无意义。