Здравствуйте, NordS, Вы писали:
NS>//раскрывающийся пункт меню(еще может содержать MenuItem и MenuGroup) NS>class MenuGroup : public MenuItemBase NS>{ NS>public: NS> CAtlArray<MenuItemBase> Items; NS>}; NS>[/code]
NS>И вот тут то встает вопрос, каким образом при получении элемента из массива различать что у меня MenuGroup ли MenuItem?
А зачем MenuGroup и MenuItem? Оставь только MenuItem. Если это не раскрывающийся пункт меню, у него Items=NULL; Если это раскрывающийся пункт меню, но не содержащий ни одного элемента, Items!=0, Items.Count=0;
Здравствуйте, NordS, Вы писали:
NS>И вот тут то встает вопрос, каким образом при получении элемента из массива различать что у меня MenuGroup ли MenuItem?
Быстро просмотрел MSDN, кажется, когда ты хранишь в CAtlArray "MenuItemBase", то ты хранишь там только базовый класс, и при добавлении в массив куски производного класса "обрезаются".
Самое простое — это завести виртуальную фунцию "IsMenuGroup", которая будет сообщать, кто там конретный потомок.
Или более красивый код от MaximE.
NS>
NS>//базовый класс пункта меню
NS>class MenuItemBase
NS>{
NS>public:
virtual bool IsMenuGroup()=0;
NS> CComBSTR Name;
NS>};
NS>//обыкновенный пункт меню
NS>class MenuItem : public MenuItemBase
NS>{
virtual bool IsMenuGroup() { return false; }
NS>};
NS>//раскрывающийся пункт меню(еще может содержать MenuItem и MenuGroup)
NS>class MenuGroup : public MenuItemBase
NS>{
virtual bool IsMenuGroup() { return true; }
NS>public:
NS>
Бррр, не люблю стандартный RTTI. Ограниченный(узнать TypeID? А я хочу его фабрику и список членов. ), тормозной(так как расчитан на все случаи жизни, типа виртуального наследования).
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, Андрей, Вы писали:
А>P.S. А>MaximE: А>Твой вариант не проходит, т.к. при добавлении элемента в массив он не может создать экземпляр класса(т.к. у нас указан MenuItemBase, а он абстрактный)
А нельзя ли поподробнее — кто именно не может создать экземпляр класса, и где эти экземпляры храняться?
Если ты в MenuItem хранишь экземпляры MenuItemBase, то ты теряешь всю информацию о наследниках из-за срезки.
ЗЫ
А вообще, нормальный ОО-дизайн не требует информации о конкретном типе объекта.
//базовый класс пункта меню
class MenuItemBase
{
public:
CComBSTR Name;
};
//обыкновенный пункт меню
class MenuItem : public MenuItemBase
{
};
//раскрывающийся пункт меню(еще может содержать MenuItem и MenuGroup)
class MenuGroup : public MenuItemBase
{
public:
CAtlArray<MenuItemBase> Items;
};
Ню ню Незнаю как на других компиляторах, ну чтоб на msvc врубить RTTD (или как там называется), надо выставить:
Во-первых ключик компилятора
Во-вторых надо чтоб хоть одна функция в классе была виртуальной
Видно, что человек не разбирается в C++, так почему же давать столь скудные ответы?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Здравствуйте, Shady, Вы писали:
S>Видно, что человек не разбирается в C++,
почему ты сделал такой вывод
S>так почему же давать столь скудные ответы?
почему же скудные? ориентир правильный, а тонкости использования RTTI со своим компилятором он поищет в сопутствующей документации к компилятору по ключевому слову typeid
Здравствуйте, yxiie, Вы писали:
Y>почему ты сделал такой вывод
Незнаю, просто такое ощущение, вопрос же простой, человек, подкованный в с++ не стал бы задовать его на рсдн, он бы знал ответ
Y>почему же скудные? ориентир правильный, а тонкости использования RTTI со своим компилятором он поищет в сопутствующей документации к компилятору по ключевому слову typeid
О! RTTI это называется По ключевому слову "typeid" в msdn нет ничего про то, что у класса должна быть хоть одна виртуальная функция (и что RTTI генерируется только для такого класса), там вскольз упоминается, что typeid примяняется для "полиморфных" классов...
Ладно, извени за придирку!
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Здравствуйте, Shady, Вы писали:
S>Здравствуйте, yxiie, Вы писали:
S>О! RTTI это называется По ключевому слову "typeid" в msdn нет ничего про то, что у класса должна быть хоть одна виртуальная функция (и что RTTI генерируется только для такого класса), там вскольз упоминается, что typeid примяняется для "полиморфных" классов...
ну нажми F1 на слове typeid, в VC7.0 покажет и какие ключики и все все все...
Здравствуйте, NordS, Вы писали:
NS>И вот тут то встает вопрос, каким образом при получении элемента из массива различать что у меня MenuGroup ли MenuItem?
А почему бы просто не завести в базовом классе переменную типа union, где хранить тип пункта меню?
[]
> А зачем MenuGroup и MenuItem? Оставь только MenuItem. Если это не раскрывающийся пункт меню, у него Items=NULL; Если это раскрывающийся пункт меню, но не содержащий ни одного элемента, Items!=0, Items.Count=0;
Мне часто приходится работать с пустыми меню и я нахожу их крайне удобными
Здравствуйте, MaximE, Вы писали:
>> А зачем MenuGroup и MenuItem? Оставь только MenuItem. Если это не раскрывающийся пункт меню, у него Items=NULL; Если это раскрывающийся пункт меню, но не содержащий ни одного элемента, Items!=0, Items.Count=0;
ME>Мне часто приходится работать с пустыми меню и я нахожу их крайне удобными
Интересно чем?
MenuGroup ведёт себя как MenuItem, отличие только в наличии субменю. Поэтому MenuGroup можно убрать. Items сделать как readonly. Если MenuItem имеет субменю, у него Items!=NULL.
Здравствуйте, Олег Гашев, Вы писали:
ОГ>MenuGroup ведёт себя как MenuItem, отличие только в наличии субменю. Поэтому MenuGroup можно убрать. Items сделать как readonly. Если MenuItem имеет субменю, у него Items!=NULL.
Это мне тут же напомнило паттерн — Композитор, кажется?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, _Winnie, Вы писали:
_W>Бррр, не люблю стандартный RTTI. Ограниченный(узнать TypeID? А я хочу его фабрику и список членов. ), тормозной(так как расчитан на все случаи жизни, типа виртуального наследования).
ну насчет тормозного это вопрос спорный, но думаю в реализации меню RTTI не будет bottleneck'ом.
Всем спасибо за советы, за основу взят вариант от Олега Гашева.
P.S. MaximE:
Твой вариант не проходит, т.к. при добавлении элемента в массив он не может создать экземпляр класса(т.к. у нас указан MenuItemBase, а он абстрактный)