е потребно виртуелно наследство од чисти апстрактни класи (интерфејси)

Зошто во кодот под компајлерот се жали дека PureAb AbstractBase е двосмислена основна класа на MultiplyInheritedClass ? Сфаќам дека имам две копии од PureAb AbstractBase во MultiplyInheritedClass и дека FirstConreteClass и SecondConreteClass ред на дијамант (и тоа навистина го поправа проблемот со кодот подолу). Но, иако имам две копии на интерфејсот, зошто кодот во MultiplyInheritedClass не ги надминува и двете и недвосмислено ја избира класата на интерфејс дефинирана во MultiplyInheritedClass ?

#include <iostream>
using namespace std;

class PureAbstractBase {
  public:
    virtual void interface() = 0;
};

// I know that changing the following line to:
// class FirstConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class FirstConcreteClass : public PureAbstractBase {
  public:
    virtual void interface() { implementation(); }
  private:
    void implementation() { cout << "This is object FirstConcreteClass\n"; }
};

// I know that changing the following line to:
// class SecondConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class SecondConcreteClass : public PureAbstractBase {
  public:
    virtual void interface() { implementation(); }
  private:
    void implementation() { cout << "This is object SecondConcreteClass\n"; }
};

class MultiplyInheritedClass : public FirstConcreteClass,
                               public SecondConcreteClass {
  public:
    virtual void interface() { implementation(); }
  private:
    void implementation() { cout << "This is object MultiplyInheritedClass\n"; }
};

Понатаму, зошто немам проблеми со следната хиерархија? Зарем класата ConcreteHandler нема три копии на AbstractTaggingInterface во овој случај? Па, зошто го нема истото прашање како примерот погоре?

#include <iostream>
using namespace std;

class AbstractTaggingInterface {
  public:
    virtual void taggingInterface() = 0;
};

class FirstAbstractHandler : public AbstractTaggingInterface {
  public:
    virtual void taggingInterface() { cout << "FirstAbstractHandler\n"; }
    virtual void handleFirst() = 0;
};

class SecondAbstractHandler : public AbstractTaggingInterface {
  public:
    virtual void taggingInterface() { cout << "SecondAbstractHandler\n"; }
    virtual void handleSecond() = 0;
};

class ThirdAbstractHandler : public AbstractTaggingInterface {
  public:
    virtual void taggingInterface() { cout << "ThridAbstractHandler\n"; }
    virtual void handleThird() = 0;
};

class ConcreteHandler : public FirstAbstractHandler,
                        public SecondAbstractHandler,
                        public ThirdAbstractHandler {
  public:
    virtual void taggingInterface() = { cout << "ConcreteHandler\n"; }
    virtual void handleFirst() {}
    virtual void handleSecond() {}
    virtual void handleThird() {}
};

Се обидувам да ја завиткам главата околу сето ова затоа што неодамна имав разговор со колега каде тој тврдеше дека ако наследуваш од чисти виртуелни часови (интерфејси) без членови на податоци, тогаш виртуелното наследување не беше потребно. Мислам дека разбирањето зошто првиот пример за кодот не работи, а вториот не би одел далеку за да го вметнам ова директно во мојата глава (и да разјаснам што точно сакаше да каже со неговиот коментар). Благодарам однапред.

13
задан bpw1621 19 June 2011 в 20:45
поделиться