2013-04-05 96 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