嵌套在C ++中传递对指针的引用

时间:2016-01-21 10:35:27

标签: c++ pointers recursion

我有一个包含类Obj实例的应用程序,每个实例都由一个ID整数标识为类成员。对象被排列为顶级对象,嵌套子对象的分支存储在std::vector中,如下所示:

/* 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类是

// 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层深层或更多时,就会出现这种情况。只有向下钻取一个级别时 才能工作。

由于我将指针作为引用传递,因此我确信它们将通过范围进行,但似乎并非如此,因为它似乎超出了范围。

任何人都可以看到此实现的问题,并可能建议改进此类对象检索实用程序的实现吗?

1 个答案:

答案 0 :(得分:2)

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

您制作了Obj的副本,而ObjRet可能会在离开范围后悬挂指针。

改为使用:

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