15

一个类可以重载公共继承接口中也存在的方法吗?看起来这是明确且有用的,但编译器(VC、Intel、GCC)都抱怨,至少在我的构造中是这样。下面是一个玩具示例。继承的反弹() 函数有两个明确的重载,但这不会编译。如果你在任一类中重命名rebound() 方法,它可以正常工作,但如果它们共享相同的成员函数名(即使它们被不同的参数类型重载!)你会得到一个致命错误“函数的参数太少称呼。”

解决方法很简单(我将重命名方法),但我只是想了解这是否是 C++ 限制(以及为什么会这样)。


#include 
class Bound {
public:
  Bound() : x0(0.0), x1(0.0) {};
  Bound(double x) : x0(x), x1(x) {};
  double width() const {return x1-x0;}
  void rebound(const Bound *a, const Bound *b);
private:
  double x0, x1;
};

void Bound::rebound(const Bound *a, const Bound *b)
{
  if (a && b) {
    x0=std::min(a->x0, b->x0);
    x1=std::max(a->x1, b->x1);
  }
}

class Node : public Bound {
public:
  Node(double x) : Bound(x), left(0), right(0) {};
  Node(Node *a, Node *b) : left(a), right(b) {rebound();}
  void rebound() { rebound(left, right); }
private:
  Node *left;
  Node *right;
};


int main() {
  Node A(1.0);
  Node B(2.0);
  Node C(&A, &B);
}
4

3 回答 3

23

你可以做三件事:

1.取消隐藏基类方法

usingNode声明中添加:

using Bound::rebound;
void rebound() { rebound(left, right); }

2.显式引用基类方法

使用绑定命名空间:

void rebound() { Bound::rebound(left, right); }

3.定义/重新定义派生类中的所有重载

将实现委托给基类(如果这是在标头中完成的,由于内联,不应该有任何惩罚):

void rebound(const Bound *a, const Bound *b) { Bound::rebound(a, b); };
void rebound() { rebound(left, right); }

更多信息: https ://isocpp.org/wiki/faq/strange-inheritance#overload-derived

于 2009-01-23T04:35:13.507 回答
2

当您在子类中声明具有相同名称但签名不同的方法时,它实际上对父类隐藏了版本。

您可以将其专门称为 Bound::rebound(...) 或使用 using 关键字。

这里

于 2009-01-23T04:41:40.000 回答
1

这称为隐藏父成员函数。您可以显式调用它(Bound::rebound(left, right)正如@Ates Goral 所说),也可以using Bound::reboundNode类定义中添加 a 。

有关更多信息,请参阅http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9

于 2009-01-23T04:41:06.930 回答