Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 要求;“公众”;在自动作用域中使用实例时访问修改器_C++ - Fatal编程技术网

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函数调用<代码>方法>代码>时,您会想到什么?注意:所有<代码>方法>代码>声明是私有的。@苏美特:这并没有任何帮助,并且“澄清您的怀疑”。毫无意义。