博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++ 向量复制_在C ++中复制向量的不同方法
阅读量:2537 次
发布时间:2019-05-11

本文共 15276 字,大约阅读时间需要 50 分钟。

c++ 向量复制

In this article, we are going to see how to copy a vector into another vector in various ways? We will also learn about shallow copy and deep copy, their differences, and consequences while checking each of the vector copy methods.

在本文中,我们将看到如何以多种方式将一个向量复制到另一个向量中? 在检查每种向量复制方法时,我们还将了解浅拷贝和深拷贝 ,它们的区别以及后果。

Before starting with the methods for copying a vector into the other, let's discuss what shallow copy and deep copy are. What are differences b/w them, and why do we need two different terms to classify the copy process.

在介绍将向量复制到另一个向量的方法之前,让我们讨论什么是浅拷贝和深拷贝。 它们之间有什么区别,为什么我们需要两个不同的术语来对复制过程进行分类。

浅拷贝与深拷贝 (Shallow copy vs Deep copy)

A vector is essentially an object which has some memory allocation upon execution. Now say you have defined and declared some vector A and you want to copy the content of A into another vector B. Now, there can be two cases, one case is we define a new vector B, but doesn't allocate any new memory for that, rather just link up to the vector A similar like vector B is pointing to the same location of vector A. Thus it has the same copy of vector A. This is known as a shallow copy. If we make any changes to vector A even after our copy operation is done, vector B will have the same changes which are not intended.

向量本质上是一个在执行时具有一些内存分配的对象。 现在说您已经定义并声明了一些向量A,并且想要将A的内容复制到另一个向量B中 。 现在有两种情况,一种情况是我们定义了一个新的向量B ,但没有为此分配任何新的内存,只是链接到向量A,类似向量B指向向量A的相同位置。 因此,它具有向量A的相同副本。 这被称为浅表副本。 如果即使在完成复制操作后对向量A进行任何更改,向量B也会具有相同的变化,这是不希望的。

On the other hand, when we create a new location for vector B and copy contents from vector A, then it's known as deep copy. If we make any change to vector A after the copy operation it won't be reflected in vector B which is of course intended.

另一方面,当我们为向量B创建一个新位置并复制向量A中的内容时,则称为Deep copy 。 如果我们在复制操作之后对向量A进行了任何更改,它都不会反映在向量B中 ,这当然是预期的。

While discussing the copy method we will detail whether it's a shallow copy or deep copy and why so that you never make any mistake using the copy method and guess it's a deep copy! (yes we often intend to have a deep copy normally).

在讨论复制方法时,我们将详细说明它是浅复制还是深复制以及原因,这样您就永远不会使用复制方法犯任何错误,而猜测它是深复制 ! (是的,我们通常通常打算复制一个深层副本)。

不同的复印方式 (Different copy methods)

1)反复复制内容 (1) Copy content iteratively)

Here we simply copy the contents of vector A into vector B iteratively. Vector B is defined as a new location, so it's of course a deep copy. We have verified that too by changing elements after our copy operation.

在这里,我们简单地将向量A的内容迭代地复制到向量B中 。 向量B被定义为新位置,因此它当然是深层副本。 我们也通过在复制操作后更改元素来验证这一点。

Example code:

示例代码:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined vector
B; //copy content iteratively for (int i = 0; i < A.size(); i++) { B.push_back(A[i]); } cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

2)递归复制内容 (2) Copy content recursively)

Here we simply copy the contents of vector A into vector B recursively. Vector B is defined as a new location, so it's of course a deep copy. We have verified that too by changing elements after our copy operation.

在这里,我们简单地将向量A的内容递归复制到向量B中。 向量B被定义为新位置,因此它当然是深层副本。 我们也通过在复制操作后更改元素来验证这一点。

Example code:

示例代码:

#include 
using namespace std;//to copy recursively//check reference is passed for vector Bvoid myrecur(int i, vector
A, vector
& B){ //base case if (i == A.size()) return; //copy content B.push_back(A[i]); myrecur(i + 1, A, B);}int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined vector
B; //copy content iteratively myrecur(0, A, B); cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

3)使用赋值运算符“ =”(覆盖当前内容) (3) Using assignment operator "=" (overwriting the current contents))

Another way to copy a vector into another is by using the assignment operator. Yes, it works perfectly! Don't try this at all for static array!. The reason behind why such assignment operator works because it simply overwrites the current members if any available, else assigns the value from where it's being copied. Below is an example and we can see, it's a deep copy.

将向量复制到另一个向量的另一种方法是使用赋值运算符。 是的,它运作完美! 根本不要尝试使用静态数组! 之所以使用这种赋值运算符,是因为它会简单地覆盖当前成员(如果有)的原因,否则会从其复制位置赋值。 下面是一个示例,我们可以看到,它是一个深层副本。

Note: In Java, assignment operator does a shallow copy only.

注意:在Java中,赋值运算符仅执行浅表复制。

Example code:

示例代码:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined and copy A //with assignment operator vector
B = A; cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

4)使用复制构造函数 (4) Using copy constructor)

We can also pass the vector A as a constructor to vector B which will invoke copy constructor and serve a deep copy.

我们还可以将向量A作为构造函数传递给向量B ,后者将调用复制构造函数并提供深层复制

Example code:

示例代码:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined and vector //A passed in the constructor //this is also considered as an //initialization method too vector
B(A); cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

5)std :: copy()函数 (5) std::copy() function)

There is another method using the std function copy(). Though it's less used you should know a variety of functions the C++ standard library has. And yes, it does a deep copy.

The copy function takes three argument

还有一种使用std函数copy()的方法 。 尽管使用较少,但您应该了解C ++标准库具有的各种功能。 是的,它可以进行深层复制。

复制函数需要三个参数

The first one is: iterator from where copy will be started: beginning of vector A

第一个是:从何处开始复制的迭代器:向量A的开始

The second one is: iterator to where copy will be ended: the end of vector A

第二个是:结束复制的迭代器:向量A的结尾

The third one is: output iterator which points to destination vector: beginning of Vector B

第三个是:指向目标向量的输出迭代器:向量B的开头

So the syntax is,

所以语法是

void copy(argumnet1, argument2, argument3)

Example code:

示例代码:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined vector
B(5); //copy using std::copy copy(A.begin(), A.end(), B.begin()); cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

A very important note about the above code:

关于上述代码的重要提示:

Check here I have defined vector B as vector<int> B(5), but if you look in earlier codes you will find I had defined like vector<int> B

检查这里我已经将向量B定义为vector <int> B(5) ,但是如果您看一下以前的代码,您会发现我已经将向量B定义为vector <int> B

Now the question is why I made the change this time. Is there any reason or I just did that! Okay, let's say we do the same as before.

现在的问题是,为什么这次我要进行更改。 有什么原因还是我只是这样做了! 好的,假设我们做的和以前一样。

Then the code will be:

然后代码将是:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined vector
B; //copy using std::copy copy(A.begin(), A.end(), B.begin()); cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Segmentation fault (core dumped)

Oops! The output is segmentation fault!. Why? Probably now you get the point. Whenever we write vector<int> B the vector has no idea about how many elements will be there and it doesn't allocate memory for elements at all. But in our copy function there is the output iterator which tries to traverse vector B, but fails as no memory allocated for elements. That's why segmentation fault and we need to allocate memory, rather say define the vector along with its elements. That's why we need vector<int> B(5). Go through my article on vector initialization methods to know in details about this. Oops, one little mistake can lead you to segmentation fault and you may just get insane to find the bug! Nice lesson I hope.

糟糕! 输出是分段错误! 。 为什么? 也许现在您明白了。 每当我们写vector <int> B时 ,向量都不知道会有多少个元素,也根本不为元素分配内存。 但是在我们的复制函数中,有一个输出迭代器试图遍历向量B,但是由于没有为元素分配内存而失败。 这就是分割错误的原因,我们需要分配内存,而不是说定义向量及其元素。 这就是为什么我们需要vector <int> B(5)的原因 。 浏览我有关矢量初始化方法的文章,以了解有关此内容的详细信息。 糟糕,一个小错误可能会导致您出现细分错误,并且您可能会疯狂地找到该错误! 我希望这堂课很好。

6)vector :: assign()函数 (6) vector::assign() function)

Vector has an inbuilt function too to copy contents from other content. It's named assign() function. It's again a deep copy method.

Vector也具有内置功能,可以从其他内容复制内容。 它被命名为assign()函数。 这又是一种深层复制方法。

The syntax is like below,

语法如下所示,

destination_vector.assign (    iterator to the beginning of source_vector,     an iterator to the end of source_vector    );

Example code:

示例代码:

#include 
using namespace std;int main(){ //vector A; //a vector of 5 element where each //element is -1 vector
A(5, -1); cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //vector B defined vector
B; //copy using vector::assign B.assign(A.begin(), A.end()); cout << "Vector A copied into vector B\n"; cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; //to check deep copy or shallow copy //changing one element in vector A A[4] = 4; cout << "After making the change...\n"; //printing vector A cout << "printing vector A:\n"; for (auto it : A) cout << it << " "; cout << endl; //printing vector B cout << "printing vector B:\n"; for (auto it : B) cout << it << " "; cout << endl; cout << "No change in B, it's deep copy!\n"; return 0;}

Output:

输出:

printing vector A:-1 -1 -1 -1 -1Vector A copied into vector Bprinting vector B:-1 -1 -1 -1 -1After making the change...printing vector A:-1 -1 -1 -1 4printing vector B:-1 -1 -1 -1 -1No change in B, it's deep copy!

Okay, that's all. So, we found all the copy methods actually do a good job as they all do deep copy and we can use any one of them blindly. Do comment and let us know which copy method you would prefer and why?

好的,仅此而已。 因此,我们发现所有复制方法实际上都做得很好,因为它们都进行深度复制,因此我们可以盲目使用其中任何一种。 请发表评论,让我们知道您喜欢哪种复制方法,为什么?

翻译自:

c++ 向量复制

转载地址:http://hzozd.baihongyu.com/

你可能感兴趣的文章
欧建新之死
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>
笛卡尔遗传规划Cartesian Genetic Programming (CGP)简单理解(1)
查看>>
mysql 日期时间运算函数(转)
查看>>
初识前端作业1
查看>>
ffmpeg格式转换命令
查看>>
万方数据知识平台 TFHpple +Xpath解析
查看>>
Hive实现oracle的Minus函数
查看>>
秒杀多线程第四篇 一个经典的多线程同步问题
查看>>
RocketMQ配置
查看>>
vs code调试console程序报错--preLaunchTask“build”
查看>>
蚂蚁金服井贤栋:用技术联手金融机构,形成服务小微的生态合力
查看>>
端口号大全
查看>>
机器学习基石笔记2——在何时可以使用机器学习(2)
查看>>
POJ 3740 Easy Finding (DLX模板)
查看>>
MySQL 处理重复数据
查看>>
关于typedef的用法总结(转)
查看>>
【strtok()】——分割字符串
查看>>
Linux下安装rabbitmq
查看>>