Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/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++_Overriding_Private_Virtual Functions - Fatal编程技术网

C++ 如果私有虚函数在派生类中被重写为公共函数,那么会出现什么问题?

C++ 如果私有虚函数在派生类中被重写为公共函数,那么会出现什么问题?,c++,overriding,private,virtual-functions,C++,Overriding,Private,Virtual Functions,可访问性检查基于对象的静态类型执行。o的类型是One*。这意味着如果One::func()是private,则o->func()将不会编译 另一方面,根据对象的动态类型,将在运行时调用哪个虚拟成员函数(即动态分派)。因此,如果One::func()是public,o->func()将调用Two::func(),因为o指向类型为Two的对象 对于您的示例代码和用例,将One::func()设为private是毫无意义的。但请注意,有一个著名的习语叫做,它使用基类的私有虚拟成员函数 其他建议: 别

可访问性检查基于对象的静态类型执行。
o
的类型是
One*
。这意味着如果
One::func()
private
,则
o->func()
将不会编译

另一方面,根据对象的动态类型,将在运行时调用哪个虚拟成员函数(即动态分派)。因此,如果
One::func()
public
o->func()
将调用
Two::func()
,因为
o
指向类型为
Two
的对象

对于您的示例代码和用例,将
One::func()
设为private
是毫无意义的。但请注意,有一个著名的习语叫做,它使用基类的
私有
虚拟成员函数


其他建议:

  • 别忘了
    删除o
  • 在基类
    One
    中添加一个虚拟析构函数。否则
    删除o将导致未定义的行为;e、 g.
    Two的析构函数可能无法调用

     error: ‘virtual void One::func()’ is private
    

  • 子类不能减轻继承限制, 尽管func是虚拟的,但继承限制仍然存在

    有关继承限制的补充视图,请参见此答案:

    请检查

    从标准:

    §11.5[类别访问权限]虚拟机的访问规则(第11条) 函数由其声明决定,不受 以后重写它的函数的规则

    使用表达式的类型在调用点检查访问 用于表示为其调用成员函数的对象。这个 定义成员函数的类中的成员函数的访问权限为 一般不知道

    如果名称查找确定可行函数为虚拟函数,则将在用于命名函数的对象表达式的静态类型的范围内检查虚拟函数的访问说明符。在运行时,可以使用完全不同的访问说明符在派生类中定义要调用的实际函数。这是因为“访问说明符”是编译时现象

    由于函数
    func()
    的访问说明符是在
    One*o
    的范围内检查的,并且在类
    One
    中是私有的,因此会产生错误


    如果
    One
    func()
    声明为public,而
    Two
    将其声明为private,则不会出现任何错误。看到这个了吗

    如果func()是基类中的纯虚函数呢?这没关系。为什么会这样?可见性是相同的,纯虚拟意味着没有实现。@ LyLee没有什么不同,如果<代码>函数()/代码>仍然是代码>私下< /COD>。@ LILL在虚拟析构函数中的行为是相同的:很好地被发现,它经常被遗忘,所以它应该不仅仅是一个建议。C++中的一个子类实际上可以改变可访问性。(或“继承限制”,以遵循您的命名法)的任何继承成员(数据或函数),例如,它本身有权访问。
     error: ‘virtual void One::func()’ is private
    
    class One {
        public:
            virtual ~One() {}
        // ...
    };