析构函数,图形和递归

时间:2015-04-23 11:53:12

标签: c++ recursion vector tree

我有一个图形对象,我想为此创建一个析构函数。但是,我对递归性并不十分舒服,而且我在自己的数据结构中有点迷失。我将展示所涉及的课程以及我的析构函数的开始。

class Graph {

private :
        Graph*               parent;
        vector<Graph>        child;
        Board                tab;
        bool                 seen;

public :
        Graph(const Board&);
        Graph(const Board&, Graph*);
        ~Graph();
        ...
};

class Board {        
    private :
        int**           tab;
        int             nbline;
        int             nbcolumn;
        Position        emptyspot;

    public  :
        Board();
        Board(int, int, Play&);
        Board(int, int);
        Board(const Board&);
        Board(int, int, ifstream&);
        ~Board();
       ...
};

位置类只有2个int(行和列)。 董事会析构工作:

Board::~Board()
{
    for(int i = 0; i < this->nbline; i++) {
        delete tab[i];
    }
    delete tab;
}

正如您猜测的那样,我想销毁我的图形节点以及以下所有节点。

这是我的开始:

Graph::~Graph() {        
    while(!child.empty()) {                
        for(vector<Graph>::iterator itr = child.begin; itr != child.end; ++itr) {
            delete child[itr];
        }
    }
}

这样我就可以递归地进入我的所有分支,对吧?当我找到一个叶子(向量为空) - 如果销毁所有东西,在父对象中会发生什么?

我不知道父母是否会将自己设置为NULL(我不这么认为),并且父矢量内存空间不会被分配,所以条件child.empty()赢了& #39; t得到满足,对吧?

  • 我如何以及何时销毁*图表?

  • 我是否冒着堆栈溢出的风险?

    • 我可以在我开始删除的根节点中调用vector.erase(),以便以递归方式销毁所有内容而不是执行for循环吗?

1 个答案:

答案 0 :(得分:2)

由于很多原因,您的析构函数不正确。

  1. 您的child成员应该是vector<Graph*>,以便您可以delete他们。
  2. 如果您的Graph有任何孩子,则您的循环无限,因为您永远不会更改child向量的大小
  3. child[itr]不是您获得与迭代器相对应的Graph*的方式,*itr是。
  4. beginend是成员函数,因此需要调用它们。
  5. 该成员应该命名为children,不是吗?
  6. 正确的循环是:

    for (vector<Graph*>::iterator itr = children.begin(); itr != children.end(); ++itr) {
        delete *itr; // this will recursively call Graph::~Graph() 
                     // on the children, and then free their memory
    }
    

    或者,在C ++ 11中,我们只是定义:

    std::vector<std::unique_ptr<Graph>> children;
    

    这样就可以为我们处理内存清理。