如何复制构造函数指针向量 C++

how to copy constructor pointer vector c++

我正在尝试为 class "Table" 创建具有以下字段的复制构造函数:

private:
    int id ;
    int capacity;
    bool open;
    std::vector<Customer*> customersList;
    std::vector<OrderPair> orderList;

我想对所有字段进行深度复制,我已经编写了以下代码,但我不确定是否对 customersList 进行了深度复制,因为它是一个指针向量。有人可以告诉我我制作的是深拷贝还是浅拷贝吗?提前谢谢你。

代码:

Table(const Table& t): capacity(t.getCapacity()), open(t.isOpen()), id(t.getId()){
    std::vector<Customer*> tmp(t.customersList);
    customersList = tmp;
}

或者我复制过度了,我应该只做这个? :

Table(const Table& t): customersList(t.customersList), capacity(t.getCapacity()), 
open(t.isOpen()), id(t.getId()){}

再次感谢!

std::vector<Customer*> 意味着它不拥有 Customer 对象,仅引用存在于其他地方的对象。在这种情况下,您可以使用编译器生成的复制构造函数来为您执行成员智能(浅)复制。例如:

Table(const Table& t) = default;

Can someone tell me if I made a deep or sallow copy?

您both/either...取决于您正在考虑的间接级别。

std::vector 的拷贝构造函数进行深拷贝。即:原始对象中的向量customersList和构造对象中的向量customersList指的是不同的内部缓冲区。如果您添加指向一个的指针,它不会自动反映在另一个向量中。

但是,向量中的元素是指针。指针具有相同的值,指向相同的 Customer 个对象,并且没有 Customer 个对象被复制。因此副本很浅。


您显示的两个建议具有相同的结果,但后者更好,因为它只对向量执行一个操作(复制构造)而不是三个(成员的默认构造、本地的复制构造、成员的复制赋值) ).如果功能正确,实现相同的更简单方法是使用隐式生成的复制构造函数:Table(const Table& t) = default; 它做同样的事情,只是直接访问成员,而不是通过成员函数。

但确实,你需要深思熟虑你要复制什么。您需要 Customer 个对象的副本吗?然后你确实需要一个自定义复制构造函数来复制初始化那些 Customer 对象。如果这样做,那么您可能应该使用智能指针向量而不是裸指针(假设您根本需要指针)。


I wanted to create another vector that will contain new pointer - a new memory allocation, but with the same data. In other words, I want to copy the data to a new memory and save the new pointers in the customersList field.

在那种情况下,您的复制构造函数不会执行您想要的操作。您有新的指针,但没有新的值,并且没有为客户对象分配内存(尽管有为向量分配的内存)。

How can I do that ?

您可以编写一个循环遍历要复制的向量。在循环中,您可以分配新的客户对象,并用向量指向的对象复制初始化它们。然后将新分配的指针插入到正在构造的成员向量中。

请注意,在这种情况下,指针将拥有。你永远不应该拥有裸指针。重申一下:在这种情况下,您应该使用智能指针(假设您完全需要指针)。

不,您还没有复制那些向量元素指向的内容。如果我猜对了你的要求,你需要继续这样做 "manually":

Table(const Table& t): capacity(t.getCapacity()), open(t.isOpen()), id(t.getId()){
    customersList.reserve(t.customersList.size());
    for (const auto old : t.customersList)
       customersList.push_back(new Customer(*old));
}

如果 Customer 是继承层次结构的基础,您将需要在每个派生 class 中执行正确的 newvirtual Customer* clone() 成员函数,以避免切片。如果不是,为什么要存储指针呢?而是存储值并为自己省去这整个麻烦。

顺便说一下,我希望您能妥善管理这些指针的生命周期,包括 delete。总的来说,如果你使用某种智能指针而不是 Customer*.

通常会更好

你是否需要 C++98/03 中的非多态答案。它处理您 customersList 中的某些指针可能不再指向任何地方的情况。

Table(Table const &t) : id(t.id), capacity(t.capacity), open(t.open), orderList(t.orderList) {
    customersList.reserve(t.customersList.size());
    std::vector<Customer *>::const_iterator b = t.customersList.begin();
    std::vector<Customer *>::const_iterator const e = t.customersList.end();
    for (; b != e; ++b) {
        if (*b) {
            customersList.push_back(new Customer(**b));
        } else {
            customersList.resize(customersList.size() + 1);
        }
    }
}