15

パブリックに継承されたインターフェイスにも存在するクラスオーバーロードメソッドはありますか?これは明白で便利なようですが、コンパイラ(VC、Intel、GCC)はすべて、少なくとも私の構造では不平を言っています。以下はおもちゃの例です。継承されたrebound()関数には2つの明確なオーバーロードがありますが、これはコンパイルされません。どちらかのクラスで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

あなたは3つのことをすることができます:

1.基本クラスのメソッドを再表示します

宣言にausingを追加します。Node

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

2.基本クラスのメソッドを明示的に参照する

Bound名前空間を使用します。

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-派生

于 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クラス定義にを追加することができます。

詳細については、 http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9を参照してください。

于 2009-01-23T04:41:06.930 に答える