就地修改向量的元素
以下内容无法按预期工作(打印 2),因为我猜,即使向量是按引用传递的,节点也是按值传递的。我该如何解决它?
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
class Node{
public:
int value;
Node(int);
void createChildren(vector<Node> &);
};
//! constructor of a single node
Node::Node(int value)
{
this->value = value;
}
void Node::createChildren(vector<Node> &nodes)
{
for (int i = 0; i < 5; i++) {
Node n(0);
nodes.push_back(n);
if (i == 0) {
value = nodes.size();
}
}
}
int main(void) {
Node a(0);
vector<Node> asdf;
asdf.push_back(a);
asdf[0].createChildren(asdf);
cout << asdf[0].value << endl;
return 0;
}
The following doesn't work as desired (print 2) because, I guess, the nodes are passed by value even though the vector is passed by reference. How could I fix it?
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
class Node{
public:
int value;
Node(int);
void createChildren(vector<Node> &);
};
//! constructor of a single node
Node::Node(int value)
{
this->value = value;
}
void Node::createChildren(vector<Node> &nodes)
{
for (int i = 0; i < 5; i++) {
Node n(0);
nodes.push_back(n);
if (i == 0) {
value = nodes.size();
}
}
}
int main(void) {
Node a(0);
vector<Node> asdf;
asdf.push_back(a);
asdf[0].createChildren(asdf);
cout << asdf[0].value << endl;
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您执行
nodes.push_back(n);
行时,向量将被调整大小,在将现有成员复制到新分配的内存块时使先前保留的引用无效。在您的情况下,createChildren
内的*this
就是这样的引用(对asdf[0])。更改其中的值不再是已定义的行为,因为该对象的析构函数已执行(尝试定义~Node()
并查看何时调用它)When you execute the line
nodes.push_back(n);
, the vector is resized, invalidating previously held references as it copies the existing members to a newly allocated memory block. In your case,*this
insidecreateChildren
is such a reference (to asdf[0]). Changing value in it is no longer defined behavior because the destructor for this object has been executed (try defining~Node()
and see when it is called)该解决方案与 Adrian Regan 所说的有些相关。
如果您在“createChildren()”方法中将另一个元素推送到节点向量上,则向量很可能需要调整自身大小。当它执行此操作时,它将所有现有元素复制到新分配的存储中。
因此,第一次发生这种情况时,它会将节点 0 的初始值复制为 0。
编译器将生成一个默认的复制构造函数,该构造函数执行按位复制。然而,仅仅实现一个复制构造函数并没有什么帮助,因为你总是会丢失节点 0.h 的更新值
。
The solution is somewhat related to what Adrian Regan sais.
If you push another element onto the vector-of-nodes in the "createChildren()" method, there's a fair chance that the vector needs to resize itself. When it does that it copies any existing elements over to the newly allocated storage.
So, the first time this happens it is copying the inital value of node 0 with value 0.
The compiler will generate a default copy constructor which does a bitwise copy. However, just implementing a copy constructor is not going to help since you will always lose the updated value of node 0.
h.
如果要将 Node 类放入向量(或任何其他容器)中,则需要确保它具有复制构造函数和运算符= 实现,否则应将指向 Node 的指针放入向量
之外您的 createChildren() 方法应在循环后将该值设置为 5。
If you are going to put the Node class into a vector (or any other container for that matter) you need to ensure that it has a copy constructor and and operator= implementation, otherwise you should put pointers to Node in the vector
Outside of this your createChildren() method should set the value to 5 after the loop.