2013-04-05 114 views
0

我有一個遞歸函數find(),它嘗試查找具有給定ID的項目。下面我從提取類的相關部分做出了榜樣編譯:遞歸函數沒有完全遞歸對象/子對象

#include <iostream> 
#include <cstdarg> 
#include <cstdio> 
#include <string> 
#include <vector> 

class Item { 
private: 
    std::vector<Item> subitems; 

public: 
    std::wstring id; 

public: 
    Item() 
    : subitems(0), id(L"") {} 

    Item(const Item& rhs) 
    : subitems(rhs.subitems.size()) { 
     for (std::size_t i = 0; i < rhs.subitems.size(); ++i) 
      subitems[i] = rhs.subitems[i]; 
     id = rhs.id; 
    } 

    Item& operator==(const Item& rhs) { 
     if (this != &rhs) { 
      for (std::size_t i = 0; i < rhs.subitems.size(); ++i) 
       subitems[i] = rhs.subitems[i]; 
      id = rhs.id; 
     } 
     return *this; 
    } 

    std::vector<Item> getSubitems() { 
     return subitems; 
    } 

    Item addSubitems(Item * item ...) { 
     va_list args; 
     va_start(args, item); 
     for (Item * arg = item; arg != NULL; arg = va_arg(args, Item *)) { 
      subitems.push_back(*item); 
     } 
     va_end(args); 

     return *this; 
    } 

    Item addSubitems(std::vector<Item>& items) { 
     for (typename std::vector<Item>::value_type &item : items) { 
      subitems.push_back(item); 
     } 

     return *this; 
    } 

    static Item * find(int id, std::vector<Item>& items) { 
     std::wstring id_str = std::to_wstring(id); 
     std::wcout << "--> find id=" << id_str << std::endl; 
     std::wcout << "size of items=" << items.size() << std::endl; 
     for (typename std::vector<Item>::value_type &c : items) { 
      std::wcout << "it .. cur id=" << c.id << std::endl; 
      if (!c.id.empty() && c.id == id_str) { 
       std::wcout << "==> found" << std::endl; 
       return &c; 
      } 

      if (!(c.getSubitems()).empty()) { 
       std::wcout << "-> find " << id << " in subitems" << std::endl; 
       std::vector<Item> subcls = c.getSubitems(); 
       std::wcout << "size of subitems=" << subcls.size() << std::endl; 
       Item * sub = find(id, subcls); 
       if (sub != NULL) { 
        std::wcout << "==> found in subitems" << std::endl; 
        return sub; 
       } 
      } 
     } 
     return NULL; 
    } 
}; 

int main() { 
    Item c1; 
    c1.id = L"0"; 
    Item c2; 
    c2.id = L"1"; 
    Item c3; 
    c3.id = L"2"; 
    Item c4; 
    c4.id = L"3"; 
    //std::vector<Item> cll4({c4}); 
    //std::vector<Item> cll3({c3}); 
    //std::vector<Item> cll2({c2}); 

    c3.addSubitems(&c4, NULL); 
    c2.addSubitems(&c3, NULL); 
    c1.addSubitems(&c2, NULL); 

    //c1.addSubitems(cll2); 
    //c2.addSubitems(cll3); 
    //c3.addSubitems(cll4); 

    std::vector<Item> items({c1}); 

    Item * c = Item::find(2, items); 
    std::wcout 
     << "Found item=" 
     << ((c != NULL && c == &c3) ? "true" : "false") << std::endl; 
    std::wcout 
     << ((c != NULL) ? c->id : L"") << std::endl; 

    return 0; 
} 

我創建幾個Items,並添加sub-Items給他們。現在我希望能夠通過使用遞歸find()方法來查找項目的ID並返回找到的項目或子項目對象。 如果我使用addSubitems()(帶有變量參數)添加項目,它將找到該項目但不返回(有效)項目對象。如果我使用addSubitems方法通過傳遞一個項目的向量find()方法不完全遞歸所有子項目。

其實我現在正坐在這個問題上,現在最後4個小時,我沒有想法,這可能是我監督或錯過的一件簡單的事情。我添加了複製構造函數/賦值運算符後綴(僅查看行爲是否有變化),但沒有。不要擔心項目ID是一個字符串類型(原因是爲了以後的序列化),這個類是在它的早期階段,所以我現在我選擇了一個字符串類型。

難道有人請指出缺陷/問題,讓這個班直!非常感謝!

回答

0

好吧,「它會找到該項目但沒有返回(有效)項目對象的問題。」是:

你發送Item *到addSubItems方法,然後你添加一個(* Item)到vector中; 這會初始化一個c'tor副本,所以之後當你做的時候是& c == & c3,顯然這是錯誤的,因爲雖然對象是INDEED相同的,但是地址不會是因爲它們是一個副本另一個。

不,我明白你爲什麼會想複製,但解決辦法是要麼測試

if (c == c3) -> activating the Item operator == 

還是分配的成員,節省了

std::vector<Item*> subitems; 

,然後問if (c == c3) -> asking about the addresses

+0

感謝您的意見。是的,的確,在閱讀你的答案之後,聽起來很清楚。現在我使用選項2(指針向量),即使我對它不滿意,但在開發過程中我可能會改變一些東西。 – 2013-04-05 11:57:09

+0

確保你分配它們 – Alon 2013-04-05 12:02:25