如果私有虚拟函数被覆盖为派生类中的公共函数,那么问题是什么
If a private virtual function is overridden as a public function in the derived class, what are the problems?
using namespace std;
#include <cstdio>
#include <iostream>
class One{
private:
virtual void func(){
cout<<"bark!"<<endl;
}
};
class Two: public One{
public:
void func(){
cout<<"two!"<<endl;
}
};
int main(){
One *o = new Two();
o->func();
}
为什么o->func()
上有错误?
我不知道其背后的机制...我认为,o->func()
应该在派生类中拨打func()
,这是公开的,所以不会有问题,但它说:
error: ‘virtual void One::func()’ is private
根据对象的静态类型执行可访问性检查。o
的类型为One*
。这意味着如果One::func()
是private
,则o->func()
不会编译。
另一方面,基于对象的动态类型,将调用虚拟成员函数(即动态调度)。因此,如果One::func()
是public
,o->func()
将调用Two::func()
,因为o
指向类型Two
的对象。
对于您的示例代码和用例,制作One::func()
private
只是毫无意义。但是请注意,有一个名为非虚拟界面的著名成语,它利用private
基类的虚拟成员函数。
其他建议:
- 不要忘记
delete o;
-
在基类
One
中添加虚拟破坏者。否则delete o;
将导致不确定的行为;例如Two
的破坏者可能不会被调用。class One { public: virtual ~One() {} // ... };
一个子类无法缓解继承限制,即使Func是虚拟的,它仍然是继承限制。
请参阅此答案,以获取有关继承限制的观点:
私人,公共和受保护的继承之间的区别
请检查访问说明器和虚拟函数。
来自标准:
§11.5[class.access.virt]虚拟的访问规则(第11条) 功能由其声明确定,不受 后来覆盖它的函数的规则。
使用表达式的类型在呼叫点检查访问 用于表示调用成员函数的对象。这 在定义的类中访问成员函数的函数是 一般来说。
如果名称查找确定可行函数为虚拟函数,则在用于命名函数的对象表达式的静态类型的范围内检查虚拟函数的访问说明符。在运行时,可以在派生类中定义要调用的实际函数,并具有完全不同的访问说明符。这是因为"访问说明符"是一种编译时间现象。
由于One *o
的范围中检查了函数func()
的访问说明符,并且在类One
中是私有的,因此会产生错误。
如果One
将func()
声明为公共,并且Two
将其私有化,则不会有任何错误。请参阅调用此私人功能并有效。你们中的任何一个都可以推荐它
- 类C++中的函数问题(LNK2019和LNK1120错误)
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 函数名是c中该函数的第一条指令的地址吗
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 输出错误,问题是找到总和5000位数字cpp
- c++无值sort()的问题是什么?
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 工会成员的析构函数似乎是自动调用的
- 我的问题是关于C++中数字和序列的重复以及如何打印它们?
- 交换函数不是在 C++ 中交换 2D 数组的元素
- 什么是钻石问题?是一系列问题还是特定问题?
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 什么是非营利组织???我的问题是我不明白为什么有人会使用它
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 问题是找到最大的负数,最小的正数
- 为什么没有参数的构造函数似乎是此代码的问题
- 我的问题是关于类成员函数作为类指针的返回类型
- 如果私有虚拟函数被覆盖为派生类中的公共函数,那么问题是什么
- C++括号和格式问题(未声明的标识符,本地函数定义是非法的)
- 这是解决mixin构造函数问题的有效方法吗