为什么我的元素在移动
Why are my deque elements moving around?
我正在实现一个简单的Tree类,以便在解析器中使用,在解析器中我需要遍历解析树的结构并逐步构建它。
这是演示该问题的类的精简版本(可在此repl.it会话中执行):
template <typename T>
class Tree {
T val;
std::deque<Tree<T>> children;
public:
Tree() {}
Tree(T value) : val(value) {}
Tree(T value, std::deque<Tree<T>> children) : val(value), children(children) {}
std::deque<Tree<T>> getChildren() { return this->children; }
void appendChild(T value) {
this->children.push_back(value);
// this->children.emplace_back(value);
std::cout << "Appended child to node with value " << this->val << ".n";
printChildren();
}
void printChildren() {
std::cout << "children for " << this << "(" << this->val << ")"
<< ": { ";
for (auto &child : this->children) {
std::cout << &child << "(" << child.val << ") ";
}
std::cout << "}n";
}
};
对于每个节点,子节点都存储在std::deque
中,因此可以将子节点添加到任意一端。在测试我的类时,我发现我不能依赖于通过增量构建树生成的结构,而不是使用初始化器列表一次性生成。
下面是一些代码来练习这个课程并展示正在发生的事情:
std::cout << "Constructing Treenn";
Tree<int> t(1);
t.appendChild(2);
t.getChildren()[0].appendChild(3);
std::cout << "nnPrinting tree from mainnn";
t.printChildren();
t.getChildren()[0].printChildren();
这具有以下输出:
Constructing Tree
Appended child to node with value 1.
children for 0x7ffe9fd41820(1): { 0xb69080(2) }
Appended child to node with value 2.
children for 0xb694a0(2): { 0xb696b0(3) }
Printing tree from main
children for 0x7ffe9fd41820(1): { 0xb69080(2) }
children for 0xb698c0(2): { }
正如您所看到的,值为2
的节点的地址每次打印出来时都是不同的。当它第一次附加到1
节点时,它具有地址0xb69080
。在它获得自己的子级之后,它具有地址0xb694a0
。然后,当从main
函数访问它时,它具有地址0xb698c0
。
此外,当它被移动时,它似乎不知何故失去了孩子。最后一行应该显示2
节点有一个值为3
的子节点。
这是怎么回事?
我想你的问题就在这里
std::deque<Tree<T>> getChildren() { return this->children; }
getChildren()
返回子级的副本。
尝试
std::deque<Tree<T>> & getChildren() { return this->children; }
// .................^
返回对内部children
的引用。
我的意思是:如果getChildren()
返回一份带有的children
t.getChildren()[0].appendChild(3);
将值为3
的子项附加到getChildren()
返回的children
副本的第一个元素。
此副本未保存,因此它是一个临时值,之后会立即销毁,丢失附加的3
子项。
相关文章:
- 在同一容器中移动元素
- 从标准容器中移动元素是否合法?
- 我可以在 std::list 中移动元素而不会使迭代器或引用无效,但是如何移动呢?
- 在数组中移动元素 SIGABRT 错误
- C++11 在列表到映射(或其他容器)之间移动元素
- 在堆栈中移动元素
- 初始化 std::数组而不复制/移动元素
- 算法,用于查找获取排序列表所需的最小移动元素到结束步骤
- 从Boost Multi_index数组移动元素
- 将一个向量附加到另一个向量时,为什么移动元素比复制它们便宜?
- memmove会移动元素(就像前面的方式相同),还是一次抓住整个内存块
- 在C++数组中移动元素
- 为什么重新分配矢量复制而不是移动元素
- 在矢量中插入元素并在其后移动元素
- 弹出后使用数组>>移动元素排队
- 从STL容器中移动元素是否会将其从该容器中移除
- 对容器进行排序,然后在保留原始排序的情况下移动元素
- 可移动元素向量的大小调整是否有效?
- 我如何构建公共数据,同时保留默认的移动元素和分配
- 扩展std::vector以从其他vector类型移动元素