我有一个图形对象,我想为此创建一个析构函数。但是,我对递归性并不十分满意,我对自己的数据结构有些迷茫。我将展示涉及的类和析构函数的开始。

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()不会得到满足,对吗?


如何以及何时销毁* Graph?
我是否有堆栈溢出的风险?


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

最佳答案

您的析构函数不正确有很多原因。


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


正确的循环为:

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;


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

关于c++ - 析构函数,图形和递归,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29822657/

10-11 22:36