在递归函数中创建 std::list of value 而不是 std::list of 指针
Create std::list of value instead of std::list of pointers in recursive function
我有这个类:
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);
}
有没有另一种方法可以做同样的工作并将obj
存储在值列表中而不是指针列表中?
在开始创建更多子对象之前,这不就是修复对象的地址吗? 为此,请先将它们放入子列表,然后递归...
void recursive(obj& parent, int n)
{
if (parent.depth == n)
return;
obj son;
son.parent = &parent;
son.depth = parent.depth + 1;
parent.children.push_back(son);
recursive(parent.children.back(), n);
}
您可以考虑在 obj
中存储唯一 ID,这样obj
的实例不会定义所表示对象的标识,而是定义其 ID 的标识。如果这样做,则可能会存储 ID 以链接相关obj
,而不是存储指针。
例如,您可以更改obj
类以包含int
字段id
:
class obj {
public:
obj()
: parent(nullptr),
depth(0)
{
// Not thread-safe; would need to get protected if multi-threaded
id = nextId++;
}
static int nextId;
int id;
int parentId;
list<int> childrenIds;
int depth; // Used only for this example
};
每当构造新obj
来表示新的逻辑"事物"时,都可以为id
字段分配一个新的唯一值。当您想要在表示相关"事物"的obj
之间建立关系时,例如,您可以使用parentId
字段而不是parent
指针字段:
void recursive(obj& parent)
{
if (parent.depth == 1) {
return;
}
obj son;
son.parentId = parent.id;
son.depth = parent.depth + 1;
recursive(son);
parent.childrenIds.push_back(son.id);
}
当您想要访问链接时,这需要更多的工作:而不是跟随指向父obj
的指针,而是需要在您维护的某个全局obj
列表中查找obj
(搜索有问题的parentId
)。
当然,这实际上取决于这些obj
真正代表什么,以及您要实现的更广泛目标......
相关文章:
- Usages of std::move
- Centos7 g++ "to_string is not in a member of std"
- 传递 std::vector of std::shared_ptr,而不是更新对象
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- PyBind11:返回对 std::vector of std::unique_ptr 的常量引用
- 是否可以使用 std::variant of std::variants
- What is the std::chrono::time_point equivalent of std::numer
- python equivalent of std::chrono::steady_clock::now();
- Strange behavior of std::vector<{QString,int*}>
- 如何在 std::map 中从 std::vector of std::p air 中获取输入?
- "terminate called after throwing an instance of std::invalid_argument' what(): stoi ?"
- Initialize std::array of std::array
- The uses of std::osyncstream?
- VC++ implementation of std::promise
- Return value of std::hash ofr (x86/x64)
- libc++ implementation of std::condition_variable_any
- constexpr version of ::std::function
- STD :: Min of std :: Chrono ::不同类型的持续时间
- 迭代一个巨大的 std::vector of std::vectors 并修改元素
- "Explicit specialization of std::iterator_traits<char *> after instantiation"(咕)