防止派生类隐藏基类的非虚函数

4
考虑我有A和B两个类,如下所示:
class A
{
   public:
   void Fun();
};

class B  : public A
{
   ....
};

作为A类的设计师,我是否有办法强制要求派生类B和其他从A继承的类无法隐藏非虚函数Fun()(并获取某种错误)?


1
你想要解决什么问题?也许有其他的方法可以解决,但我认为你所描述的方式不可能实现。 - Mike Seymour
那应该由编译器处理。它应该在函数隐藏时给出警告。我不知道任何其他可能防止这种行为的方法。 - Adi
@Adi 客户端可能会意外隐藏一个名称,而不提供其父类非虚函数的定义。 - juanchopanza
@juanchopanza 是的,我同意这可能是无意中发生的,但是类设计者仍然应该处理这些事情吗?我的观点是不应该。在这种情况下会发出编译器警告,客户端应该足够纠正它的代码。 - Adi
很遗憾,@Adi,通常没有编译器警告。而且在现实世界中,有一些糟糕的旧代码库过度使用了继承,很容易在特定类型的无数继承函数中错过一个名称。在设计良好的代码中,这应该不是一个大问题。 - juanchopanza
显示剩余4条评论
1个回答

3
如果你希望非虚拟成员函数总是可访问的,那么只需要将它包装在命名空间作用域的自由函数中即可。
namespace revealed {
    void foo( A& o ) { o.foo(); }
}

现在B类客户端总是可以执行

void bar()
{
    B o;
    revealed::foo( o );
}

然而,无论B类引入多少隐藏重载的方法,客户端仍然可以直接调用。
void bar2()
{
    B o;
    A& ah = o;
    ah.foo();
}

他们可以做什么?
void bar3()
{
    B o;
    o.A::foo();
}

所以,几乎所有的收获都是更易于理解的注释和意图沟通。

也就是说,远非评论中所说的不可能,可用性是您默认拥有的...


@ Alf...我没有听懂你的回答...我的意思是要强制执行一个规则,即所有派生类都应该使用基类函数...不应该通过提供自己的实现来隐藏它... - Arun
@Arun:你不能强迫别人使用你的任何结构。但是你可以避免提供替代方案。然后,如果他们想要你实现提供的功能,他们必须使用唯一的方法来实现它。这个答案只是展示了如何始终访问基类功能。以及如何使这更加容易。 - Cheers and hth. - Alf
除了您所说的,还可以写成 B o; o.A::foo();。@Cheersandhth.-Alf - syam
@匿名的点踩者:请解释一下你的点踩。也许你只是不满意这种语言?那么表达不满的方式不应该是对解释语言的答案进行点踩。 - Cheers and hth. - Alf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接