forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Виртуальное наследование (http://forum.boolean.name/showthread.php?t=10811)

wolfhound512 24.11.2009 22:27

Виртуальное наследование
 
Всем привет, посоветуйте каким способом можно решить данную задачу:
Есть такая иерархия классов
Код:

cBase -> cElem1 -> cElem2 -> cElem...
cBase -> cElem11 -> cElem12 -> ...
...
cBase -> cPrimary

Необходима возможность создать класс на основе cPrimary и любого из cElem, т.е.
cPrimary + cElemN -> cPrimElem
Класс cPrimary основан на базовом классе, для возможности доступа к его функциям и для переопределения пары виртуальных функций (которые переопределяются только в cPrimary).

1) Для этой цели вполне бы подошло виртуальное наследование, однако есть небольшое НО. Если базовый класс имеет только параметризованные конструкторы, то этот самый конструктор придется вызывать в каждом классе, имеющем в основе базовый класс.
Это не совсем удобно и в некоторых случаях не допустимо.
Например в цепочке "cBase -> cElem1 -> cElem2" конструктор класса cElem2 может просто не знать всех параметров необходимых конструктору базового класса.

Можно ли как-то избавиться от необходимости вызывать конструктор базы из каждого класса?

2) Второй вариант - не основывать cPrimary на cBase, а передать ему указатель на нее.
Код:

class Base {
  void draw();
}
class Primary {
  Base* base;
  Primary(Base* b) { base = b; }
}
class Elem : Base(), Primary(this) {}

func(Primary* prim) {
  prim->base->draw()
}

Elem MyElem;
func(MyElem);

Но как быть с переопределением виртуальных функций базового класса в этом случае?

3) Встроить cPrimary в базовый класс с переменной отвечающей за вкл/выкл cPrimary. Наиболее просто, но базовый класс итак громоздкий, да и лишние переменные для классов не использующих cPrimary таскать не хочеться.

Надеюсь понятно объяснил. Какие еще варианты возможны или как улучшить эти?
Заранее спасибо.

jimon 24.11.2009 23:11

Ответ: Виртуальное наследование
 
wolfhound512
что-то ты перемудрил однако, где такое нужно то ? если я правильно понимаю где ты такое получил, то я шел по первому пути, пришлось в каждом классе делать буферные конструкторы которые пропускали параметры сверху вниз

wolfhound512 25.11.2009 19:33

Ответ: Виртуальное наследование
 
Почему перемудрил? Есть у меня "элементы" основанные на базовом классе. Эти элементы могут быть первичными (cPrimary), а могут и не быть. Если элемент является первичным, то можно пользоваться дополнительными функциями, + две функции работают по-другому. Вроде бы ничего мудреного.
Вставить же такое разделение сразу после базового класса (т.е. все обычные от базы, а все первичные от базы+primary) нельзя, так как элемент может стать первичным только аж в четвертом покалении.
Изначально я пошел по третьему пути, не задумываясь над тем, что можно сделать иначе. Поэтому в базовом классе есть переменная, отвечающая за статус элемента. Т.е. во всех специфических функциях идет проверка: является ли элемент первичным. Минусы этого способа я описал выше.

Что за буферные конструкторы?
У меня проблема такая:
cBase (virtual)-> cElem1 -> cElem2 -> cElem3

Т.к. cBase наследовался виртуально, то в cElem3 нужно вызвать его конструктор. Допустим cElem3 знает все аргументы необходимые базе, но подразумевается, что он должен передать их cElem2, который может их изменить или проигнорировать и передать дальше свои аргументы. А так как вызывать конструктор базы приходится прямо из cElem3, то эта цепочка обламывается.
Как ты это обошел?

jimon 25.11.2009 23:25

Ответ: Виртуальное наследование
 
wolfhound512
что-то плохо представляю, для меня первичный объект и не первичный объект это два разных объекта, я бы тогда действительно шел по третьему пути

wolfhound512 26.11.2009 12:38

Ответ: Виртуальное наследование
 
Это разные классы на общем основании. Просто бывает необходимость создать первичный класс на основании обычного...
Может я плохо объясняю...

Вобщем спасибо, оставлю пока как есть, т.е. 3й вариант.


Часовой пояс GMT +4, время: 00:13.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot