2016-01-21 61 views
0

我有一个应用程序,它包含一个类Obj的实例,每个实例通过ID integer标识为一个类成员。的对象被布置为顶层对象与存储在std::vector这样嵌套子对象的分支:在C++中嵌套传递指针的指针

/* Obj tree with L ID as: 
* 
*  Obj (L 0) 
*   | 
*  Obj (L 1) 
*   | 
*  Obj (L 2) 
* 
*/ 

我已经定义了一个实用方法的指针重定向到层次结构中的一个对象,它具有给定的ID。这被实现为从具有子对象的每个对象到实用程序的递归调用,直到找到对象或达到层次结构的底部。递归应该展开并返回指向应用程序范围的指针。因为这个原因,我已经将指针作为参考传递,所以可以在适当的递归调用中改变它。

源代码如下:

Object类

// Object class 
class Obj { 

    friend class Utils; 
    friend class App; 

public : Obj(int ID_L) // Overloaded constructor 
    { 
     this->ID_L = ID_L; 
    } 

    // Public and private IDs 
    public : int ID_L; 

    // Vector of sub objects 
    std::vector<Obj> subObj; 

    // Add sub-obj method 
    public : void addSubObj(int num_layers) { 

     // Add the sub-obj 
     subObj.emplace_back(this->ID_L + 1); 

     // Add one underneath if necessary 
     if (subObj.back().ID_L <= num_layers) { 
      subObj.back().addSubObj(num_layers - 1); 
     } 

    }; 

}; 

实用类是

// Utility class 
class Utils { 

// Static method to return pointer to obj in the hierarchy 
public : static void getObj(Obj*& ObjTree, int ID_L, Obj*& ObjRet) { 

    // Try match on the top of the tree given 
    if (ObjTree->ID_L == ID_L) { 
     ObjRet = ObjTree; // Match found so update pointer and return  
     return; 

    } else { 

     // Loop through array of subObjs on this Obj 
     for (Obj o : ObjTree->subObj) { 

      // Create pointer to object in present scope 
      Obj* O = &o; 

      // Look for match on this subObj 
      Utils::getObj(O, ID_L, ObjRet); // Recursvie call passing reference of pointer along and address of present sub-Obj and its children 

       // If a match found then return the non-null pointer 
       if (ObjRet != NULL) { 
        return; 
       } 

      } 

     } 

     // Specified Obj has not been found in the tree 
     return; 

    } 

}; 

的应用程序类是

// Application class 
class App { 

public : void run() { 

    // Create object tree as above 
    Obj TopObj(0);   // Top level obj 
    TopObj.addSubObj(2);  // Left side branch 

    // Create pointer to Obj to do further stuff with 
    Obj* _o; 

    // Create pointer to tree 
    Obj* Tree = &TopObj; 

    // Loop over all desired ID combos and return pointer to appropriate Obj in hierarchy 
    for (int l = 0; l <= 2; l++) { 

      // Null the pointer in preparation for next Obj 
      _o = NULL; 

      // Try to fetch a particular Obj from ObjTree 
      Utils::getObj(Tree, l, _o); 

      // If pointer is not null then Obj has been found so try to read IDs from it 
      if (_o != NULL) { 
       std::cout << "FOUND -- L" << l << " : reading ID from pointer as L" << _o->ID_L << " : " << _o << std::endl; 
     } 

    } 

} 

}; 

和条目点在这里:

// Entry point 
int main(int argc, char* argv[]) { 

    // Start application 
    App a; 
    a.run(); 
} 

调试时我已经写了指针_o屏幕的价值,我可以看到,当物体被发现其更改,然后随着递归解开保持其价值。但是,当试图访问它指向的对象将应用程序范围中的ID打印到屏幕上时,这些数字是垃圾。 的情况就是这样,当对象被发现到层次结构的2层或更多。它确实工作时只向下钻一层。

由于我通过指针作为参考,我相信他们将通过范围进行,但似乎并非如此,因为它看起来像对象超出范围。

任何人都可以看到这个实现的问题,也许建议一个改进的实现这样一个对象检索工具

+4

需要所有的代码向人们展示了问题?你可以发布[MCVE](关键字最小)吗? – bolov

+1

[OT]:'Obj(){};'让成员未初始化,应该可能被删除。 – Jarod42

+0

[OT]:Obj *的更好的签名是'static Obj * getObj(Obj&ObjTree,int ID_L,int ID_R)' – Jarod42

回答

2

for (Obj o : ObjTree->subObj) { 
    Utils::getObj(&o, ID_L, ID_R, ObjRet); 

你做的ObjObjRet副本都可能有悬摆指针一次离开范围。

使用,而不是:

for (Obj& o : ObjTree->subObj) { 
    Utils::getObj(&o, ID_L, ID_R, ObjRet); 
+0

谢谢Jarod的建议和快速回答。 – CodingLumis