这可能是一个幼稚的问题,但简单来说如何实现与 std::vector 相同的复制构造函数?

问题描述

我有一个简单的 Box 容器,带有一个带 Car 的简单实现

#include <iostream>
#include <vector>

struct Car { 
    Car() { puts("def"); }
    Car(Car const& other) { puts("copy"); }
    Car& operator=(Car const& other) {
        puts("assign");
        return *this;
    }
};


struct Box {
    size_t size;
    Car* ptr;

    Box(size_t size) 
        : size(size),ptr{new Car[size]} 
        {}
    
    Box(Box const& other) 
        : size{other.size} 
        {
            ptr = new Car[size];
            for (int i = 0; i < size; i++)
                ptr[i] = other.ptr[i]; // hits operator=
    }
};

int main() {
    Box b(2);
    Box b3 = b;    
    std::cout << std::endl;

    std::vector<Car> v(2);
    std::vector<Car> v2 = v;
}

o/p

def
def
def
def
assign
assign

def
def
copy
copy
  • std::vector 复制并调用复制构造函数,而 Box 不会。 std::vector 的复制构造函数是如何实现的?我做错了什么?
  • std::vector 的内存分配是如何处理的,为什么认构造函数在 std::vector 中只调用了两次,而在 Box调用了 4 次?任何解释就足够了

解决方法

std::vector 使用分配器而不是使用 new 运算符。关键的区别在于 new 运算符构造了数组中的每个元素。但是 vector 分配原始内存并且只按需构造元素。您可以通过使用 operator new(而不是 new 运算符)、malloc、某些分配器或其他方式来实现相同的效果。然后使用placement-new 来调用构造函数。在析构函数中,您必须单独调用所有元素的析构函数,然后才释放内存。见:

此外,您的 Box 类需要一个 operator=,因为默认类会出错。和一个破坏者。它正在泄漏内存。

,

可能在分配的较低层的实现中使用了引用计数机制。