【发布时间】:2012-07-05 08:24:32
【问题描述】:
我有这门课:
class obj
{
public:
obj()
: parent(nullptr),
depth(0)
{ }
obj* parent;
list<obj> children;
int depth; // Used only for this example
};
为了填充我的数据结构,我使用如下递归函数:
void recursive(obj& parent)
{
if(parent.depth == 1)
return;
obj son;
son.parent = &parent;
son.depth = parent.depth + 1;
recursive(son);
parent.children.push_back(son);
}
以这种方式为例:
obj root;
recursive(root);
如果你注意你可以看到,如果递归函数中的测试是:
if(parent.depth == n)
return;
对于n >= 2,此代码将不起作用(一旦退出递归函数,“孙子”root->son->son 的父级的存储地址 - 等等 - 将不是有效地址)。
解决此问题的一种方法是使用指针列表 (list<obj*> children) 而不是值列表:
void recursive(obj& parent)
{
if(parent.depth == 2)
return;
obj* son_ptr = new obj();
son_ptr->parent = &parent;
son_ptr->depth = parent.depth + 1;
recursive(*son);
parent.children.push_back(son_ptr);
}
是否有另一种方法可以完成相同的工作并将objs 存储在值列表中而不是指针列表中?
【问题讨论】:
-
你可以使用工厂来创建对象吗?
-
这是一个design pattern。有一个“工厂”对象,该对象创建
objs 并将每个对象的内部保存的唯一 ID 映射到其当前指针。每个obj可以保留对工厂对象的引用,并在复制构造函数期间告诉工厂新地址并使旧地址无效。然后你可以保留一个父 ID,并在需要时向工厂索要它的指针。 -
我不认为我可以使用,但我不确定,因为我以前从未使用过“工厂”......无论如何,谢谢!
-
尼克:你不知道怎么做,有人提出了一些听起来很有希望的东西,说“我不认为我可以使用它[因为我以前没有做过]/谢谢无论如何”真的是不屑一顾、不欣赏和适得其反——如果你在你现在不会问之前解决了这个问题。你为什么不说“对不起,麻烦了,但我不知道如何实施你的建议,你能给我更多的帮助吗?”。
-
目前的问题是不明确的。我们不知道你为什么要按照你所说的去做。我们不知道要求——什么可以改变,什么不能改变。如果你澄清了问题,我可以举一个简短的例子,但在那之前我不会猜测什么会起作用或不会起作用。
标签: c++ pointers recursion c++11