Требуется предусмотреть расширение функциональности некоторого класса GLScene (не обязательно весь функциональный набор будет использован в финальной сборке).
Функциональность связана с рисованием некоторых сцен (тестовых).
Для этого создаем классы примеси Scene1Mix, Scene2Mix. Каждый из классов хранит указатель w на объект типа окно QGLWidget на котором будет выполняться рисование.
Вопрос: как правильно передать указателю w указатель на безымянный объект типа QGLWidget (т.е. на GLScene)?
Или подскажите более подходящее архитектурное решение.
class GLScene: public QGLWidget {
...
};
class Scene1Mixin {
QGLWidget * w;
public:
Scene1Mix( QGLWidget * _w ) { w = _w ; }
draw1(){ w.glBegin(/* ...*/;}
}
class Scene2Mixin {
QGLWidget * w;
public:
Scene2Mix( QGLWidget * _w ) { w = _w ; }
draw2(){ w.glBegin(/* ...*/;}
}
class Scene1: public GLScene, public Scene1Mix {
Scene1( /*...*/ ) { /* w = this???; ...*/ draw1(); }
}
поправил заголовок, чтобы не вводить во смущение — Кодт
Здравствуйте, gencoder, Вы писали:
G>Вопрос по архитектуре.
G>Требуется предусмотреть расширение функциональности некоторого класса GLScene (не обязательно весь функциональный набор будет использован в финальной сборке). G>Функциональность связана с рисованием некоторых сцен (тестовых).
G>Для этого создаем классы примеси Scene1Mix, Scene2Mix. Каждый из классов хранит указатель w на объект типа окно QGLWidget на котором будет выполняться рисование.
G>Вопрос: как правильно передать указателю w указатель на безымянный объект типа QGLWidget (т.е. на GLScene)? G>Или подскажите более подходящее архитектурное решение.
Уберите всё из конструктора и замените private на protected:
Хотелось бы сделать несколько иное в итоге: перед сборкой проекта просто сконструировать новый класс путем наследования базового класса и некоторой примеси (или нескольких примесей)
class FinalScene: public Scene, public Scene25Mixin, public Scene125Mixin
{
public:
FinalScene(QWidget * p): Scene(p) { magicDrawFirst(); /*from 25*/ magicDrawSecond(); /*from 125*/ }
};
P.S.1 просто "закинуть" в класс несколько методов (использование порождающих паттернов здесь не нужно, т.к. до сборки проекта будет набираться функционал из классов примесей)
P.S.2 без шаблонов похоже никак ?
Здравствуйте, kov_serg, Вы писали:
_ _>Уберите всё из конструктора и замените private на protected: _>
Здравствуйте, gencoder, Вы писали:
G>Хотелось бы сделать несколько иное в итоге: перед сборкой проекта просто сконструировать новый класс путем наследования базового класса и некоторой примеси (или нескольких примесей) G>
G>class FinalScene: public Scene, public Scene25Mixin, public Scene125Mixin
G>{
G>public:
G> FinalScene(QWidget * p): Scene(p) { magicDrawFirst(); /*from 25*/ magicDrawSecond(); /*from 125*/ }
G>};
G>
G>P.S.1 просто "закинуть" в класс несколько методов (использование порождающих паттернов здесь не нужно, т.к. до сборки проекта будет набираться функционал из классов примесей) G>P.S.2 без шаблонов похоже никак ?
Здравствуйте, kov_serg, Вы писали:
_>Вот то что вы хотите, но лично бы я так не делал _>
_>struct Mix : virtual Base {};
_>
почему вы против mixin class (в смысле классов предоставляющих некоторый дополнительный интерфейс или функционал, и не предполагающий непосредственного инстанцирования)?
Re[5]: Minix в С++ или как получить доступ к безымянным пред
Здравствуйте, gencoder, Вы писали:
G>Здравствуйте, kov_serg, Вы писали:
_>>Вот то что вы хотите, но лично бы я так не делал _>>
_>>struct Mix : virtual Base {};
_>>
G>почему вы против mixin class (в смысле классов предоставляющих некоторый дополнительный интерфейс или функционал, и не предполагающий непосредственного инстанцирования)?
Я не mixin-ов как в D, идея хорошая, но лично я против того треша и угара который генерирует компилятор C++ в случаях виртуального наследования.
Re: Minix в С++ или как получить доступ к безымянным предкам
Mixin-ы имеет смысл делать разве что в случае, когда методы mixin-а расширяют интерфейс целевого класса:
class Scene1Mixin {
public :
void draw() {...}
void clear() {...}
...
};
class Scene1 : public GLScene, public Scene1Mixin {
...
};
Scene1 sc1;
sc1.draw(); // Это Scene1Mixin::draw.
Если вам нужно именно это, и в mixin-классах нужно иметь ссылку на GLScene (а шаблонами вы пользоваться не хотите), то можно использовать виртуальные методы:
class Scene1Mixin {
protected :
virtual GLScene & scene() = 0;
public :
void draw() { GLScene & s = scene(); ...}
void clear() { GLScene & s = scene(); ...}
...
};
class Scene1 : public GLScene, public Scene1Mixin {
protected :
virtual GLScene & scene() { return *this; }
...
};
Если внутренности mixin-класса не должны становиться частью интерфейса целевого класса, то можно вообще обойтись без mixin-ов:
namespace scene1_impl {
void draw(GLScene & scene) { ... }
void clear(GLScene & scene) { ... }
...
}
class Scene1 : public GLScene {
public :
Scene1() { using namespace scene1_impl; draw(*this); ... }
...
};
Re: Minix в С++ или как получить доступ к безымянным предкам
Здравствуйте, Кодт, Вы писали:
К>Есть ещё одна волшебная техника, называется CRTP
... К>Минусы — шаблоны, программирование мясом наружу. К>Плюсы — никаких лишних косвенностей, — ни виртуальных функций, ни указателей.
Вобщем как обычно, оптимальное решение выглядит не эстетично.
А эстетичное, не оптимально. Так и живём.