C++ vector 构造函数和赋值问题

标签 c++

我对以下语句的第 2 行和第 3 行中发生的事情感到困惑。据我了解

line2 ( vector<A> vec2(vec1); ) :对于存储在 vec1 中的每个 A 实例,将调用一个复制构造函数并将其存储在 vec2 中。令我困惑的是,即使我没有指定自定义复制构造函数,默认复制构造函数也会创建 A 的实例,可能会调用 A 和 B 的默认构造函数,但是然后,实际上正确地将 A 的成员数组的原始值初始化为拷贝和 A 的成员变量 b 的 vector 的值到拷贝的 B 的 vector 。那就是免费的深度复制。这是正确的吗?

line3 ( vector<A> vec3 = vec2; ) :不是调用复制构造函数,而是通过默认构造函数创建 A 的实例,然后调用存储实例的赋值运算符来初始化它。在这里,我再次获得免费的深度复制。

1. vector<A> vec1;
2. vector<A> vec2(vec1);
3. vector<A> vec3 = vec2;

其中 A 的定义如下所示。

class B
{
public:
    vector<int> db;
};

class A
{
public:
    char data[5];
    int x;
    B bee;
};

这里是证明深度复制正在发生的主要方法

int main()
{
    A a, b;
    a.data = {'a','b','c','d','\0'};
    a.x = 1;
    a.bee.db.push_back(99);
    a.bee.db.push_back(100);


    b.data = {'z','x','y','w','\0'};
    b.x = 2;
    b.bee.db.push_back(1);
    b.bee.db.push_back(2);

    vector<A> vec;
    vec.push_back(a);
    vec.push_back(b);

    map<int, std::vector<A>> map1;
    vector<A> vec1(vec);

    map1[1] = vec1;

    std::vector<A> vec2 = map1[1];

    cout << vec2[0].data<< endl;
    cout << vec2[0].bee.db[0] << endl;

    vec2[0].x = 77777;
    vec2[0].data = {'c','o','p','y','\0'};

    cout << "vec1[0].x: " << vec1[0].x << endl;
    cout << "vec1[0].data: " << vec1[0].data << endl;
    return 0;
}

最佳答案

首先,std::vector的所有拷贝和赋值都是深拷贝, 至少在 C++11 之前。 (在 C++11 中,还有一些版本 涉及移动语义。)

其次,您的评价:

`std::vector<A> vec3 = vec2;

不是很正确。因为vec2的类型是一样的 作为被初始化的变量,这完全像 你的情况 2.(如果类型不同,正式地, 将调用一个转换构造函数来转换权利 hand side 到正确的类型,然后是复制构造函数 会被使用。但是允许编译器优化 复制。)

还有:如果你写过:

std::vector<A> vec3;
vec3 = vec2;

编译器会默认构造一个空的vec3,然后 分配它。但作业仍会调用拷贝 每个 A 的构造函数(而不是赋值运算符) 对象,因为没有任何构造的 A 对象 vec3 当你做赋值时(赋值只能是 一个完全构造的对象)。

最后:关于深拷贝:std::vector 拷贝为 正如它所知道的那样深,这是包含的元素。然后, 包含的元素有责任更深入 (或不)。默认的复制构造函数将做一个成员 成员拷贝(所以如果所有包含的元素都有拷贝 构造函数,你是安全的),但是如果有例如原始指针, 您可能必须自己编写,才能为对象提供拷贝 你想要的语义。

关于C++ vector 构造函数和赋值问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17793773/

相关文章:

c++ - 解释 C++ 中语句和表达式的区别

c++ - 删除标点查询

c++ - 在子类中调用父函数

c++ - 在 C++ 中键入安全数字常量

c++ - 如何覆盖 C++ 模板类中的纯虚函数?

c++ - 为什么在将大小为整数变量的数组声明时会出现编译器错误?

c++ - 覆盖 DirectX 结构的新建和删除

c++ - 涡轮 C++ : Generate object code for malloc function

c++ - 如何将指针和指针传递给函数?

c++ - 模板类静态在最终二进制文件中是否在共享库中以不同方式实例化?