Krolick
@Krolick
...не только ценный мех!

Можно ли обойтись без виртуального наследования?

У меня есть ромбовидное наследование интерфейсов: общий интерфейс IReadableDataset виртуально наследуется двумя другими: IEditableDataset и IStatisticalDataset. В свою очередь, есть реализация CDatasetImpl, которая реализует IStatisticalDataset и IEditableDataset.


Можно ли обойтись без виртуального наследования? Например, с помощью какого-то хитрого трюка с шаблонами?

class IReadableDataset
{
public:
    virtual void SayReadableDataset() const = 0;
};

class IEditableDataset: virtual public IReadableDataset
{
public:
    virtual void SayEditableDataset() const = 0;
};

class IStatisticalDataset: virtual public IReadableDataset
{
public:
    virtual void SayStatisticalDataset() const = 0;
}

class CDatasetImpl: public IEditableDataset, public IStatisticalDataset
{
public:
    virtual void SayReadableDataset() const;
    virtual void SayEditableDataset() const;
    virtual void SayStatisticalDataset() const;
};
  • Вопрос задан
  • 5200 просмотров
Пригласить эксперта
Ответы на вопрос 4
Если классы, названия которых начинаются с «I» — это интерфейсы, то есть у них нет своих данных и логики, то такое множественное наследование не считается моветоном.
Но, возможно, в вашем случае можно IEditableDataset переименовать в IWritableDataset и не наследовать его от IReadableDataSet.
Ответ написан
@vScherba
Это классический случай множественного наследования интерфейсов. Т.к. они не содержат состояния, нужно просто убрать ключевое слово virtual.
Кстати, для чего Вам здесь понадобилось виртуальное наследование?
Ответ написан
@tbd
еквивалент на шаблонах например такой, только не сильно красиво…
class ReadableDataset
{
public:
    virtual void SayReadableDataset() const = 0;
};

template<class Base>
class EditableDataset: public Base
{
public:
    virtual void SayEditableDataset() const = 0;
};

template<class Base> 
class StatisticalDataset: public Base
{
public:
    virtual void SayStatisticalDataset() const = 0;
};

class CDatasetImpl: public StatisticalDataset<EditableDataset<ReadableDataset> >
{
public:
    virtual void SayReadableDataset() const
    {
        std::cout << "SayReadableDataset" << std::endl;
    };
    virtual void SayEditableDataset() const
    {
        std::cout << "SayEditableDataset" << std::endl;
    };
    virtual void SayStatisticalDataset() const
    {
        std::cout << "SayStatisticalDataset" << std::endl;
    };
};

template<class T>
void statistic(const StatisticalDataset<T>& x)
{
    x.SayReadableDataset();
    x.SayStatisticalDataset();
}

template<class T>
void edit(EditableDataset<T>& x)
{
    x.SayReadableDataset();
    x.SayEditableDataset();
}

void read(const ReadableDataset& x)
{
    x.SayReadableDataset();
}

int main()
{
    CDatasetImpl a;

    read(a);
    edit(a);
    statistic(a);
    return 0;
}
Ответ написан
@Door
Нет, нельзя.
Это как пытаться не применять ключевое слово virtual для указания того, что данный метод — виртуальный.
Т.е. у Вас есть все условия для применения виртуального наследования — и это не костыль — без его применения — вот это костыль.
Не нравится виртуальное наследование — передумайте свою иерархию классов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы