代码之家  ›  专栏  ›  技术社区  ›  user

C++矢量复制元素?

  •  4
  • user  · 技术社区  · 14 年前

    我想在C++中使用一个动态数组(类似于一个数组或Java中的一个向量)。
    在这个例子中是T1,T2…对象被复制或只将其地址添加到向量?
    我是否需要为节点类实现一个复制构造函数,或者默认的构造函数将进行一个“正确的”复制(因为类中有一个指针)?
    或者我应该声明 vector<Node*> 而不是为了避免复制?
    我需要实现一个析构函数来删除 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;
    }
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   Alan    14 年前

    在你的例子中 vector<Node> 将存储节点的副本,因此 t1 , t2 将被复制。

    另外,的默认复制构造函数 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和指针),因此存储副本是可以的。如果您的节点类进行了深度复制,那么从性能角度来看,使用它会更好 vector<Node*>

        2
  •  2
  •   Timo Geusch    14 年前

    std::vector 而其他C++标准库容器具有值语义,换句话说,它们希望保存实际对象而不是指向对象的指针。因此,无论何时将对象放入标准库容器中,容器都会复制它。值语义具有某些含义,例如,如果容器持有指向对象的指针,则对容器的破坏进行自动清理,从而导致内存泄漏;在这种特定情况下,您需要自己手动删除指向对象。

    我的建议是,如果您有复制成本低或复制成本高但不经常被复制的对象,请将它们作为一个值放入容器中。如果需要容器保存多态对象或经常复制、复制对象成本高昂的对象,请使用 boost::shared_ptr<> 或使用适当的 boost::ptr_xxx 像一个容器 boost::ptr_vector .