質問

私はこれらの抽象クラスのFooBarがあるとします:

class Foo;
class Bar;

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

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

私は、派生クラスのConcreteFooConcreteBarを持っていることをさらに仮定します。私はcovariantlyこのようなfoo()bar()メソッドの戻り値の型を改良したい:

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

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

私たちの最愛のシングルパスコンパイラはそのConcreteBarBarから継承されます知らないので、これはコンパイルされません、となるようConcreteBarは完全に合法共変戻り値の型があります。それが継承について、コンパイラは何も教えてくれないので、ConcreteBarを宣言平野前方には、いずれか、動作しません。

これは私が一緒に暮らす必要があります++ Cの欠点ですか実際にこのジレンマを回避する方法がありますか?

役に立ちましたか?

解決

あなたは偽のそれは非常に簡単にすることができますが、静的型チェックを失います。あなたはdynamic_castsstatic_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()); }

他のヒント

静的な多型は、あなたの問題を解決していませんか? テンプレート引数によって派生クラスで基本クラスを給餌? だから、基本クラスは、派生タイプを知っているし、適切な仮想を宣言するのでしょうか?

あなたが宣言することはできません以来ので

共分散は、継承図に基づいています。

class ConcreteBar : public Bar;

共分散についてコンパイラに指示するので、決してます。

しかし、あなたはテンプレートの助けを借りてそれを行うことができ、ConcretFooを宣言::テンプレートとそれ以降の境界などのバーは、あなたがこの問題を解決することができます。

これはどうます。

template <class BarType>
class Foo
{
public:
    virtual BarType* bar() = 0;
};

template <class FooType>
class Bar
{
public:
    virtual FooType* foo() = 0;
};

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

class ConcreteBar : public Bar<ConcreteFoo>
{
public:
    ConcreteFoo* foo();
};
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top