Hi, I have developed a little class to help implement dynamic menus in
our
application which has a UI. This allows our engine to send a MenuItem
object to the UI which is an observer of the engine, then the UI can
construct
its menu based on the info in the object. The MenuItem is based on the
composite
design pattern so it contains a vector of child MenuItems, this allows
sub menus
to passed in aswell.
I currently don't know how to implement a copy constructor for this,
any ideas?
The vector won't contain any base class pointers to derived objects if
that
makes things easier. Second i read in Effective C++ not return handles
to
object internals which i seem to be doing in the :
const std::vector<MenuItem*>& SubMenuItems() const; method
I can't see how to get round this. Any other comments welcome.
Thanks
#include <string>
#include <vector>
#include <memory>
class MenuItem
{
public:
MenuItem();
MenuItem(std::wstring name, int id);
virtual ~MenuItem();
int Id() const;
std::wstring Name() const;
const std::vector<MenuItem*>& SubMenuItems() const;
void AddSubMenu(std::wstring name, int id);
bool SubMenuPresent() const;
typedef std::vector<MenuItem*SubMenuItem;
private:
MenuItem(const MenuItem& item);
MenuItem& operator=(const MenuItem&);
private:
std::wstring m_itemName;
int m_id;
SubMenuItem m_subMenuItems;
};
MenuItem::MenuItem():m_itemName(L""),m_id(0)
{
}
MenuItem::MenuItem(std::wstring name, int
id):m_itemName(name),m_id(id)
{
}
MenuItem::~MenuItem()
{
// Iterate through all submenuitems
SubMenuItem::iterator it = m_subMenuItems.begin();
while ( it != m_subMenuItems.end() )
{
delete *it;
it = m_subMenuItems.erase(it);
}
}
int MenuItem::Id() const
{
return m_id;
}
std::wstring MenuItem::Name() const
{
return m_itemName;
}
const std::vector<MenuItem*>& MenuItem::SubMenuItems() const
{
return m_subMenuItems;
}
bool MenuItem::SubMenuPresent() const
{
return !m_subMenuItems.empty();
}
void MenuItem::AddSubMenu(std::wstring name, int id)
{
std::auto_ptr<MenuItemitem(new MenuItem(name, id));
m_subMenuItems.push_back(item.get());
item.release();
}
int main()
{
// Engine code would do this and pass the object to the UI
MenuItem item(L"File", 0);
item.AddSubMenu(L"New", 1);
item.AddSubMenu(L"Edit", 2);
// UI code would read the item object and construct menu
std::vector<MenuItem*>::const_iterator it =
item.SubMenuItems().begin();
while( it != item.SubMenuItems().end())
{
// Create submenu etc
++it;
}
return 0;
}