C++ 关于std::vector 的拷贝和赋值

关于std::vector 可能存在浅拷贝问题场景:

std::vector 是一个模板类,用于表示大小可变的数组。当你尝试拷贝或赋值一个 std::vector 时,实际上发生的是浅拷贝,即只拷贝了 vector 的元数据(如内存地址、大小和容量),而不是它包含的元素。如果 vector 包含指针或其他需要深度拷贝的对象,则在拷贝后和原始 vector 对象中的对象会指向同一个内存地址,这可能会导致问题,如违反对象唯一性原则、指针悬挂等。

解决方法:

为了解决浅拷贝的问题,你需要进行深拷贝。这可以通过以下几种方式实现:

  1. 手动拷贝每个元素:

std::vector<MyClass> v1;
// 填充 v1
std::vector<MyClass> v2;
for (const auto& elem : v1) {
    v2.push_back(elem); // 对于支持拷贝构造的类型,这会进行深拷贝
}

     2. 使用标准库函数 std::for_each 和 std::back_inserter

std::vector<MyClass> v1;
// 填充 v1
std::vector<MyClass> v2;
std::for_each(v1.begin(), v1.end(), [&](const MyClass& elem) {
    v2.push_back(elem);
});

3. 利用 std::vector 的拷贝构造函数和 std::vector::assign 方法:

std::vector<MyClass> v1;
// 填充 v1
std::vector<MyClass> v2(v1.begin(), v1.end()); // 拷贝构造
// 或者
std::vector<MyClass> v2;
v2.assign(v1.begin(), v1.end()); // assign 方法

4. 如果 MyClass 有自己的拷贝构造函数进行深拷贝,可以直接使用 std::vector 的默认拷贝构造函数或者 operator= 进行深拷贝。

 

std::vector<MyClass> v1;
// 填充 v1
std::vector<MyClass> v2 = v1; // 拷贝构造
// 或者
std::vector<MyClass> v2;
v2 = v1; // 赋值操作

 确保 MyClass 或其他存储在 vector 中的类型支持深拷贝,并且在拷贝构造函数、赋值运算符以及析构函数中正确处理内存。

定义std::vector 成员的结构体拷贝:

包含std::vector 的结构体直接赋值是可以的,不存在浅拷贝的问题。vector 调用赋值运算符时候,新的vector 会重新申请一块堆内存来存放元素数据,原来的vector 的堆内存释放或者修改不会对新的vector 有影响。

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>

using namespace std;

struct DataInclueVector
{
 unsigned int data0;
 int data1;
 std::vector<int> dataVec;
};

DataInclueVector g_dataIncludeVec{};

void printLog()
{   
    //printing vector
    cout << "print vec data:" << endl;
    for (int x : g_dataIncludeVec.dataVec)
        cout << x << " ";
    cout << endl;

}



void copyDataIncludeVec(DataInclueVector & dataVec)
{
	g_dataIncludeVec = dataVec;
}

void initData()
{
	DataInclueVector dataIncludeVec{1,2,{3,4}};
        dataIncludeVec.dataVec.push_back(5);
        copyDataIncludeVec(dataIncludeVec);
	printLog();
        dataIncludeVec.dataVec.erase(dataIncludeVec.dataVec.begin());
        std::vector<int> ().swap(dataIncludeVec.dataVec);
}

int main()
{
    initData();
    printLog(); 
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值