سؤال

لنفترض أن لدي هذه الفصول الدراسية المجردة Foo و Bar:

class Foo;
class Bar;

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

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

لنفترض ألا يكون لدي الفصل المشتق ConcreteFoo و ConcreteBar. وبعد أريد أن أؤكد coviantly نوع العودة foo() و bar() طرق مثل هذا:

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

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

هذا لن يترجم منذ مترجم تمرير واحد الحبيب لا يعرف ذلك ConcreteBar سوف يرث من Bar, ، و ايضا ذلك ConcreteBar هو عودة covariant القانونية تماما. بطلون إلى الأمام يعلن ConcreteBar لا يعمل، سواء، لأنه لا يخبر المترجم بأي شيء عن الميراث.

هل هذا قصير ل C ++، سأضطر إلى العيش مع أو هل هناك بالفعل طريقة حول هذه المعضلة؟

هل كانت مفيدة؟

المحلول

يمكنك مزيفها بسهولة تماما، لكنك تفقد التحقق من النوع الثابت. إذا استبدلت dynamic_casts بواسطة 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()); }

نصائح أخرى

لا تعدد الأشكال الثابتة حل مشكلتك؟ إطعام الفئة الأساسية مع الفئة المشتقة من خلال حجة القالب؟ لذلك سوف يعرف الطبقة الأساسية نوع المشتق وتعلن افتراضيا مناسب؟

يعتمد Covariare على مخطط الميراث، لذلك لأنك لا تستطيع أن تعلن

class ConcreteBar : public Bar;

وبالتالي لا توجد وسيلة لإخبار التحويل البرمجي عن التباين.

ولكن يمكنك القيام بذلك بمساعدة القوالب، وتعلن Concretfoo :: Bar كقالب وتحتما لاحقا يسمح لك بحل هذه المشكلة

وماذا عن هذا.

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