回答
Composite模式將是一個合適的應用程序在這裏:
(維基百科:) http://en.wikipedia.org/wiki/Composite_pattern
你的情況:
- 創建一個基類叫做「菜單「(這對應於上圖中部件部分)
- 創建一個名爲「菜單項」(這對應於上述圖中的葉一部分)
- 創建稱爲「子菜單」派生類派生類(這對應於上述圖中的複合部分) SubMenu可以包含更多的菜單 - 可以是更多MenuItem或SubMenu的。
您可以通過實現與各子對象的計數器實現的基於它們的插入順序至一合成「子菜單」上菜單元素所需的順序:每次調用aSubMenu.add(newMenuItemOrSubMenu)
時間,aSubMenu
應該增加自己的計數器和標記的新項目與訂購號碼。 (實現的精確細節是你的,你不必在所有使用單獨的計數器,只使用一個列表或數組)
謝謝s.chen。 – dchhetri
也許這:
class MenuNode
{
public:
MenuNode(std::string new_label);
void Add(MenuNode * new_node);
private:
std::string label;
std::vector<MenuNode *> children; // changed to vector to preserve order
};
用法:
MenuNode menu("root"),
file("File"),
edit("Edit"),
open("Open..."),
close("Close"),
save("Save..."),
prefs("Preferences"),
yes_foo("Activate Foo"),
no_foo("Deactivate Foo");
menu.Add(&file);
menu.Add(&edit);
file.Add(&open);
file.Add(&close);
file.Add(&save);
edit.Add(&prefs);
prefs.Add(&yes_foo);
prefs.Add(&no_foo);
表示:
Main Menu
File
Open...
Close
Save...
Edit
Preferences
Activate Foo
Deactivate Foo
提防着明顯的缺陷與這個例子中,ADDRES的依賴(可能)臨時變量。你將無法在函數中創建它並返回它。
實現的瑣碎部分也丟失了,例如沒有辦法遍歷示例代碼中節點的私有狀態。
我想我會推薦動態內存和'unique_ptr'。這個答案缺乏封裝。但這個答案是正確的想法。 –
等等,不,該矢量應該直接包含'MenuNode's。 http://ideone.com/kU2RPa –
將爲所有向量實現或工作做存在不使用間接平的嗎? – Wug
使用樹。無論如何,這在樹中最好定義。
其中:rootNode連接到A
,B
,C
,D
。 B
連接到ba
和bb
。 C
連接到Ca
。等等
桑普森臣所說的複合設計模式是爲實現我做了一個小的開發者監視器的正確方法,讓你選擇從菜單結構中的一些測試方法。
我有一個基類的「菜單項目」我從中導出的子菜單和葉子(菜單項)。一個葉子只是執行一些事情,而一個子菜單打開另一個菜單級別。
例如基類可能喜歡類似(如果你喜歡用shared_pointers):
/*************************************************************//*!
* @brief The base class for all menu entry types (sub menus and sub menu entries/items)
******************************************************************/
class MenuEntry : public boost::enable_shared_from_this<MenuEntry>
{
public:
virtual ~MenuEntry(){}
/**************************************************************//*!
* @brief Default implementation to add menu entries; has to be re implemented
* @param[in] newSubMenuEntry - the new menu entry (another sub menu or leaf)
**************************************************************/
virtual void add(boost::shared_ptr<MenuEntry> newSubMenuEntry)=0;
/*****************************************************************//*!
* @brief Default implementation for call to menu entries; always returns false
* @return false - the function has not been re implemented
****************************************************************/
virtual bool call(void)
{
// the member function has not been re-implemented
return false;
}
/*****************************************************************************//*!
* @brief Default implementation, has to be reimplemented
* @return emptyVector - an empty vector
*********************************************************************************/
virtual std::vector<boost::shared_ptr<MenuEntry> > getChildren(void)
{
std::vector<boost::shared_ptr<MenuEntry> > emptyVector;
return emptyVector;
}
/*******************************************************************************//*!
* @brief Gives a pointer to the parent of the actual menu entry
* @return m_parent - pointer to the parent
******************************************************************************/
boost::shared_ptr<MenuEntry> parent(void)
{
return m_parent;
}
/***************************************************************************//*!
* @brief Default implementation for selecting a menu entry
* @param[in] desiredMenuEntry - the desired menu entry which shall be selected
* @return notExisting - a pointer to <b>this</b>
**********************************************************************************/
virtual boost::shared_ptr<MenuEntry> select(boost::shared_ptr<MenuEntry> desiredMenuEntry)=0;
/**************************************************************************//*!
* <B>Criticality: C0 \n\n</B>
* @brief Sets a pointer to the parent of new menu entry
* @param[in] pointerToParent - pointer to the parent
****************************************************************************/
void setParent(boost::shared_ptr<MenuEntry> pointerToParent)
{
m_parent = pointerToParent;
}
/***************************************************************************//*!
* @brief Default implementation for destroying children
*****************************************************************************/
virtual void destroy(void)=0;
protected:
/************************************************************************//*!
* @brief Constructor for a menu entry (sub menu or leaf)
* @param[in] menuEntryName - the name for the sub menu or leaf
*************************************************************************/
MenuEntry(std::string menuEntryName)
{
m_menuEntryName = menuEntryName;
}
};
在選擇方法我通過檢查返回值是否如果我有執行什麼葉,或子菜單,爲此我必須改變我的指針。
爲了方便,你可以添加哪些找到你所有的子菜單中的子菜單項顯示其結構與您實際菜單路徑或類似的標題行的方法,或方法...另一個想法是對的方法掃描菜單樹以避免雙重菜單項asf。
- 1. 什麼都可以使用數據結構來表示
- 2. 我可以更改redis數據結構列表來設置
- 3. 我將如何在JavaScript中表示以下菜單結構?
- 4. 我可以使用哪種數據結構/類來表示一對多關係?
- 5. 有什麼方法可以用來構建領域結構以及數據?
- 6. Java數據結構表示
- 7. 有效的數據結構來表示矩陣
- 8. 數據結構單鏈表
- 9. 結構菜單
- 10. 如何創建多個子菜單及其數據庫結構?
- 11. 可以使用UML來表示文檔層次結構嗎?
- 12. 什麼數據結構可以用來表示Python中樹中的多個子項?
- 13. 子菜單沒有顯示。
- 14. 結構如何用來表示複數
- 15. asp:DropDownList - 可能有子菜單?
- 16. 沒有顯示可擴展列表視圖的子菜單
- 17. 使用數據的下拉菜單 - 顯示子菜單
- 18. 正確的數據結構來表示數獨謎題?
- 19. 表示數字段的數據結構
- 20. 如下所示以表格結構顯示數據
- 21. 以樹狀結構顯示數據
- 22. [數據結構]:選擇一個數據結構來構建一個圖表
- 23. 指針可以是數據結構嗎?
- 24. 有沒有可以打印出malloc數據結構的命令?
- 25. 有沒有可以快速合併的地圖數據結構?
- 26. mySQL中的菜單表結構
- 27. IVR菜單(DTMF鍵)的表格結構
- 28. 用重複的節點結構來表示分層數據
- 29. NoSQL數據庫可以容納以下數據結構?
- 30. 樹數據結構C++庫,可以在控制檯中顯示?
你需要一個遞歸關係。 –
使用樹?每個節點都有一個標籤,可以有零個或多個孩子,可以推廣到任意數量的嵌套菜單。根節點的標籤被忽略,只考慮其子節點。 – Wug
@Seth我明白你的評論,但我不知道如何將它放入代碼 – dchhetri