深拷贝,就是对数据成员逐一赋值。但是如果类中含有指针类型数据,则这种按数据成员逐一赋值的方法将会产生错误。
1、浅拷贝例子
1 #include <iostream>
2 #include <cstring>
3
4 using namespace std;
5
6 class Student{
7 char *name;
8 float score;
9 public:
10 Student(char *name1,float score1);
11 ~Student();
12 };
13
14 Student::Student(char *name1,float score1)
15 {
16 name = new char[strlen(name1)+1];
17 if(0 != name)
18 {
19 strcpy(name,name1);
20 score = score1;
21 }
22 cout << "构造" << " " << name1 << endl;
23 }
24
25 Student::~Student()
26 {
27 cout << "析构" << " " << name << endl;
28 name[0] = '\0';
29 delete []name;
30 }
31
32 int main(int argc,char *argv[])
33 {
34 Student stu1("张三",99);
35 Student stu2 = stu1;
36
37 return 0;
38 }
程序运行结果为:
构造 张三
析构 张三
析构
free(): double free detected in tcache 2
已放弃 (核心已转储)
2、代码解析
程序开始运行,创建对象stu1时,调用构造函数,用运算符new从内存中动态分配一块空间,字符指针name指向这个内存块,如图所示,这时产生第1行输出“构造 张三”。执行语句"Sudent stu2=stu1;"时,因为没有定义拷贝构造函数,于是就调用默认的拷贝构造函数,把对象stu1的数据成员(字符指针name和浮点数score )逐个复制到stu2的对应数据成员中,使得stu2与stu1完全一样,但并没有新分配内存空间给stu2,如图所示。主程序结束时,对象逐个被撤销,先撤销对象stu2,第1次调用析构函数,用运算符delete释放动态分配的内存空间,并同时得到第2行输出“析构 张三”,如图所示;撤销对象stu1时,第2次调用析构函数,因为这时指针name所指的空间已被释放,所以第3行输出显示“析构 葺葺葺葺”,字符串“张三”被随机字符取代;当执行析构函数中的语句"delete []name;"时,企图释放同一空间,从而导致了对同一内存空间的两次释放,这当然是不允许的,必然引起运行错误。
3、解决方案
显示的定义一个自定义的拷贝构造函数,使之不但复制数据成员,而且还为对象stu1和stu2分配各自的内存空间,这就是深拷贝。
1 #include<iostream>
2 #include<cstring>
3
4 using namespace std;
5
6 class product{
7 public:
8 product(char *n,int p,int q);
9 product(const product &p );
10 ~product();
11 void buy(int money);
12 void get()const;
13 private:
14 char *name;
15 int price;
16 int quantity;
17 };
18 product::product(char *n,int p,int q)
19 {
20 name = new char[30];
21 strcpy(name,n);
22 price = p;
23 quantity = q;
24 }
25 product::product(const product &p)
26 {
27 name = new char[strlen(p.name)+1];
28 strcpy(name,p.name);
29 price = p.price;
30 quantity = p.quantity;
31 }
32
33 product::~product()
34 {
35 name[0] = '\0';
36 delete []name;
37 }
38
39 void product::buy(int money)
40 {
41 int num;
42 num = money/price;
43 cout << "买" << " " << num << " " << "个产品" << endl;
44 }
45
46 void product::get()const
47 {
48 cout << quantity << endl;
49 }
50
51 int main()
52 {
53 product pr1("张三",25,100);
54 product pr2(pr1);
55 product pr3 = pr1;
56 pr2.buy(520);
57 pr3.get();
58
59 return 0;
60 }
对比上一个代码例子,多了一个关于product(const product &p );的构造函数定义。
输出结果如图所示:
————————————————
版权声明:本文为CSDN博主「Samuel Chen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42442875/article/details/95471170