C++矢量复制元素?

发布于 2024-09-10 20:51:28 字数 1142 浏览 12 评论 0原文

我想在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云朵有点甜 2024-09-17 20:51:29

在您的示例中,vector 将存储节点的副本,因此 t1t2 将被复制。

此外,Node 的默认复制构造函数将创建“浅”复制。因此

Node* head = new Node();
Node* next = new Node();
head->other_node = next;
Node* other_head = new Node(*head);

*(other_head->other_node)*(head->other_node) 是同一个节点,这取决于您决定这是否是您想要的行为。

关于析构函数:您应该只删除/释放类实例分配的内存,除非您有令人信服的理由来获取内存的所有权。就您的列表而言,一般来说,由于您的列表没有分配 other_node 指向的内存,因此不应删除它。

性能方面,由于复制节点(一个 int 和一个指针)的成本相当低廉,因此存储副本是可以的。如果您的 Node 类进行了深层复制,那么从性能角度来看,使用 vector 会更好

In your example vector<Node> will store copies of your nodes, so t1,t2 will be copied.

Also, the default copy constructor for Node will make a "shallow" copy. Thus

Node* head = new Node();
Node* next = new Node();
head->other_node = next;
Node* other_head = new Node(*head);

*(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*>

情仇皆在手 2024-09-17 20:51:29

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 appropriate boost::ptr_xxx container like a boost::ptr_vector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文