Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.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++,可能重复: 问题: 它能够调用派生类函数,即使它是私有的。这怎么可能 现在,如果将继承访问说明符从public更改为protected/private,则会出现编译错误: 'type cast' : conversion from 'Derived *' to 'base *' exists, but is inaccessible 注意:我知道继承访问说明符的概念。所以在第二种情况下,由于它是派生的私有/受保护的,所以它是不可访问的。但我想知道第一个问题的答案。任何输入都将受到高度赞赏。访

可能重复:

问题:

  • 它能够调用派生类函数,即使它是私有的。这怎么可能
  • 现在,如果将继承访问说明符从public更改为protected/private,则会出现编译错误:

    '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()时,编译器可能根本不知道
    派生的
    (或
    子类
    ),更不用说对
    派生的::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
    }