是否有任何理由使重写的C++虚函数的权限与基类不同?这样做有危险吗?
例如:
class base { public: virtual int foo(double) = 0; } class child : public base { private: virtual int foo(double); }
在C++常见问题解答说,这是一个坏主意,但没有说为什么.
我已经在一些代码中看到了这个习惯用法,我相信作者试图让这个类最终,基于一个假设,即不可能覆盖私有成员函数.但是,本文显示了重写私有函数的示例.当然,C++ faq的另一部分建议不要这样做.
我的具体问题:
在派生类和基类中使用不同的虚拟方法权限是否存在任何技术问题?
有没有合理的理由这样做?
Eclipse.. 40
你确实得到了令人惊讶的结果,如果你有一个孩子,你不能打电话给foo,但是你可以把它扔到基地,然后打电话给foo.
child *c = new child(); c->foo; // compile error (can't access private member) static_cast(c)->foo(); // this is fine, but still calls the implementation in child
我想你可以设想一个你不想暴露函数的例子,除非你把它当作基类的一个实例.但是,这种情况突然出现的事实表明,在可能被重构的线路上的某个地方有一个糟糕的OO设计.
你确实得到了令人惊讶的结果,如果你有一个孩子,你不能打电话给foo,但是你可以把它扔到基地,然后打电话给foo.
child *c = new child(); c->foo; // compile error (can't access private member) static_cast(c)->foo(); // this is fine, but still calls the implementation in child
我想你可以设想一个你不想暴露函数的例子,除非你把它当作基类的一个实例.但是,这种情况突然出现的事实表明,在可能被重构的线路上的某个地方有一个糟糕的OO设计.
问题是Base类方法是声明其接口的方式.从本质上讲,它是"你可以对这类对象做的事情."
在Derived类中,你创建了Base已声明为public private的东西,你正在拿走一些东西.现在,即使Derived对象是"is-a"Base对象,你应该能够对Base类对象做一些你无法对Derived类对象做的事情,打破了Liskov Substitution Prinicple
这会在你的程序中引起"技术"问题吗?也许不吧.但它可能意味着您的类的对象不会以用户期望它们的行为方式运行.
如果你发现自己处于你想要的状态(除了在另一个答案中提到的弃用方法),你可能有一个继承模型,其中继承不是真正建模"is-a"(例如,斯科特迈尔斯的例子Square继承自Rectangle,但是你无法改变Square的宽度而不像它的高度那样,你可能需要重新考虑你的阶级关系.
没有技术问题,但最终会出现公共可用功能取决于您是否具有基指针或派生指针的情况.
在我看来,这将是奇怪和混乱.