17

これらの抽象クラスがFooあり、Bar

class Foo;
class Bar;

class Foo
{
public:
  virtual Bar* bar() = 0;
};

class Bar
{
public:
  virtual Foo* foo() = 0;
};

ConcreteFooさらに、派生クラスとを持っていると仮定しConcreteBarます。foo()bar()メソッドの戻り型を次のように共変的に改良したいと思います。

class ConcreteFoo : public Foo
{
public:
  ConcreteBar* bar();
};

class ConcreteBar : public Bar
{
public:
  ConcreteFoo* foo();
};

ConcreteBar私たちの最愛のシングルパスコンパイラは、がから継承することを知らないため、これはコンパイルされません。Barしたがって、これConcreteBarは完全に合法的な共変リターン型です。プレーンフォワード宣言ConcreteBarも、コンパイラに継承について何も通知しないため、機能しません。

これは私が一緒に暮らさなければならないC++の欠点ですか、それとも実際にこのジレンマを回避する方法がありますか?

4

4 に答える 4

5

非常に簡単に偽装できますが、静的な型チェックが失われます。dynamic_castsをbyに置き換えるとstatic_casts、コンパイラが内部で使用しているものがありますが、動的または静的な型チェックはありません。

class Foo;
class Bar;

class Foo
{
public:
  Bar* bar();
protected:
  virtual Bar* doBar();
};

class Bar;
{
public:
  Foo* foo();
public:
  virtual Foo* doFoo();
};

inline Bar* Foo::bar() { return doBar(); }
inline Foo* Bar::foo() { return doFoo(); }

class ConcreteFoo;
class ConcreteBar;
class ConcreteFoo : public Foo
{
public:
  ConcreteBar* bar();
protected:
  Bar* doBar();
};

class ConcreteBar : public Bar
{
public:
   ConcreteFoo* foo();
public:
   Foo* doFoo();
};

inline ConcreteBar* ConcreteFoo::bar() { return &dynamic_cast<ConcreteBar&>(*doBar()); }
inline ConcreteFoo* ConcreteBar::foo() { return &dynamic_cast<ConcreteFoo&>(*doFoo()); }
于 2009-08-11T09:33:13.313 に答える
4

静的ポリモーフィズムはあなたの問題を解決しませんか? テンプレート引数を介して派生クラスを基本クラスに供給しますか? したがって、基本クラスは派生型を認識し、適切な仮想を宣言しますか?

于 2011-02-14T19:08:42.087 に答える
2

共分散は継承図に基づいているため、宣言できないため

class ConcreteBar : public Bar;

したがって、共分散についてコンパイラに伝える方法はありません。

しかし、テンプレートの助けを借りてそれを行うことができ、 ConcretFoo::bar をテンプレートとして宣言し、後で境界を設定することでこの問題を解決できます

于 2009-08-11T09:33:32.657 に答える