C++矢量复制元素?
我想在 C++ 中使用动态数组(类似于 Java 中的 ArrayList 或 Vector。)
在此示例中,是复制 t1、t2...对象还是仅将其地址添加到向量中?
我是否需要为 Node 类实现一个复制构造函数,或者默认构造函数是否会生成“正确的”副本(因为类中有一个指针)?
或者我应该声明一个 vector
而不是这个以避免复制?
我是否必须实现析构函数来删除 other_node
指针,或者它可以被程序使用并仍然存储在 vector
中吗?
#include <vector>
using namespace std;
class Node {
public:
int id;
Node* other_node;
};
int main(int argc, char** argv) {
vector<Node> nodes;
Node t1;
t1.id = 0;
t1.other_node = NULL;
Node t2;
t2.id = 1;
t2.other_node = &t1;
Node t3;
t3.id = 2;
t3.other_node = &t2;
Node t4;
t4.id = 3;
t4.other_node = &t1;
nodes.push_back(t1);
nodes.push_back(t2);
nodes.push_back(t3);
nodes.push_back(t4);
for (vector<Node>::iterator it = nodes.begin(); it != nodes.end(); it++) {
if (it->other_node) {
printf("%d (other.id: %d)\n", it->id, it->other_node->id);
} else {
printf("%d (other.id: NULL)\n", it->id);
}
}
getchar();
return 0;
}
I would like to use a dynamic array in C++ (something like an ArrayList or a Vector in Java.)
In this example are the t1, t2... objects are copied or only its address is added to the vector?
Do I need to implement a copy constructor for Node class or will the default constructor make a "proper" copy (because there is a pointer in the class)?
Or should I just declare a vector<Node*>
instead of this to avoid copying?
And do I have to implement a destructor to delete the other_node
pointer or may it be used by the program and still be stored in the vector
?
#include <vector>
using namespace std;
class Node {
public:
int id;
Node* other_node;
};
int main(int argc, char** argv) {
vector<Node> nodes;
Node t1;
t1.id = 0;
t1.other_node = NULL;
Node t2;
t2.id = 1;
t2.other_node = &t1;
Node t3;
t3.id = 2;
t3.other_node = &t2;
Node t4;
t4.id = 3;
t4.other_node = &t1;
nodes.push_back(t1);
nodes.push_back(t2);
nodes.push_back(t3);
nodes.push_back(t4);
for (vector<Node>::iterator it = nodes.begin(); it != nodes.end(); it++) {
if (it->other_node) {
printf("%d (other.id: %d)\n", it->id, it->other_node->id);
} else {
printf("%d (other.id: NULL)\n", it->id);
}
}
getchar();
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的示例中,
vector
将存储节点的副本,因此t1
、t2
将被复制。此外,
Node
的默认复制构造函数将创建“浅”复制。因此*(other_head->other_node)
与*(head->other_node)
是同一个节点,这取决于您决定这是否是您想要的行为。关于析构函数:您应该只删除/释放类实例分配的内存,除非您有令人信服的理由来获取内存的所有权。就您的列表而言,一般来说,由于您的列表没有分配
other_node
指向的内存,因此不应删除它。性能方面,由于复制节点(一个 int 和一个指针)的成本相当低廉,因此存储副本是可以的。如果您的 Node 类进行了深层复制,那么从性能角度来看,使用
vector
会更好In your example
vector<Node>
will store copies of your nodes, sot1
,t2
will be copied.Also, the default copy constructor for
Node
will make a "shallow" copy. Thus*(other_head->other_node)
is the same Node as*(head->other_node)
It's up to you to decide if that is the behavior you want.Regarding destructors: You should only delete/free memory that your class instance allocated, unless you have a compelling reason to take ownership of the memory. In the case of your list, in general since your list did not allocate the memory pointed by
other_node
it should not delete it.Performance wise, since your Node is fairly inexpensive to copy (an int and a pointer), storing a copy is okay. If your Node class did a deep copy, then it would be better from a performance stand point to use
vector<Node*>
std::vector
和其他 C++ 标准库容器具有值语义,换句话说,它们期望保存实际对象而不是指向对象的指针。因此,每当您将对象放入标准库容器时,容器都会复制它。值语义具有某些含义,例如,如果容器保存指向对象的指针,则容器销毁时会自动清理,从而导致内存泄漏;在这种特殊情况下,您需要自己手动删除指向的对象。我的建议是,如果您有复制成本低或复制成本高但不经常复制的对象,请将它们作为值放入容器中。如果您需要容器保存多态对象或频繁复制、复制成本高昂的对象,请使用
boost::shared_ptr
或使用适当的boost:: 将它们保存在容器中。 ptr_xxx
容器,如boost::ptr_vector
。std::vector
and the other C++ standard library containers have value semantics, in other words they expect to hold actual objects rather than pointer to objects. So, whenever you put an object into a standard library container, the container copies it. Value semantics have certain implications like the automatic clean up on destruction of the container causing a memory leak if your container holds pointers to objects; in that particular case you need to manually delete the pointed-to objects yourself.My recommendation would be that if you have objects that are either cheap to copy or expensive to copy but don't get copied often, put them into the container as a value. If you require the container to hold polymorphic objects or frequently copied, expensive to copy objects, hold them in the container either using a
boost::shared_ptr<>
or use the appropriateboost::ptr_xxx
container like aboost::ptr_vector
.