Применение множественному наследованию в C++
Недавно понял, что похоже нашел возможно единственное полезное применение виртуальному множественному наследованию в C++, в котором базовый класс не является чисто абстрактным, т. е. содержит реализацию методов и переменные-члены.
Когда используешь паттерн Observer с абстрактным Subject, например при реализации Model-View с абстрактными моделями, то в интерфейсе абстрактного Subject должны быть объявлены методы для регистрации и дерегистрации обозревателей, например так (в примере использован Boost.Signals):
class my_model {
public:
virtual connection connect_changed(const std::function<void()> & h) = 0;
};
При этом во всех конкретных реализациях модели этот метод будет делать ровно одно и то же: подключаться к сигналу Boost.Signals:
class my_model_impl: virtual public my_model {
public:
connection connect_changed(const std::function<void()> & h) override {
return changed_signal_.connect(handler);
}
private:
signal<void()> changed_signal_;
};
Понятно, что my_model_impl может реализовывать много разных интерфейсов, которые в свою очередь могут быть унаследованы от my_model, поэтому могут возникать случаи, когда my_model будет участвовать несколько раз в иерархии наследования.
Если метод connect_changed во всех реализациях делает одно и то же, то почему бы не перенести его реализацию в класс my_model? Ну и вообще это логично: сигнал - это часть интерфейса, а не реализации интерфейса.
class my_model {
public:
connection connect_changed(const std::function<void()> & h) {
return changed_signal_.connect(handler);
}
private:
signal<void()> changed_signal_;
};
class another_model: virtual public my_model {
...
};
class my_model_impl: virtual public my_model,
virtual public another_model {
// nothing to do with signals
};
Получаем виртуальное множественное наследование от my_model.
comments powered by Disqus