用C++跟你聊聊“原型模式” (复制/拷贝构造函数)
从简历投递的故事说起
本来今天不打算用别人的故事了,但是吧,技术这东西,枯燥无味,如果我们连学个东西干嘛用都不知道,那学来干嘛?所以我觉得,这个入门应用场景是很重要的。
今天我去面试了,我需要在简历上填写我的项目经验,格式都是一水的:”XXXX - XX - XX,做过XX项目,任XX职务,收获XXXX“···
很显然,这可以用一个项目经验类来实现。
但是这一水的项目经验下来,每个经验都要初始化一个实例,成何体统?
好在我项目没过几个,还是可以赏心悦目的。
这时,就可以考虑让一个实例,有多个分身,每个分身再通过类方法修改其成员属性,岂不美哉?那要怎么分身?分身乏术啊,如果不熟悉类的复制构造函数的话。
复制构造函数
知道构造函数的人一般都知道,构造函数分为”深构造“和”浅构造“。如果不知道的话,也不用去别的地方找了,一般来说结果不会很满意,因为我找过了。
浅复制
看这样一个栗子:
class A{};
A *a = new A();
A *b = a;
- 1
- 2
- 3
像这样把一个对象直接传给另一个对象,一般情况下就是浅复制,是系统默认提供的一种构造方式。但是这种构造方式有什么潜在风险呢?因为是系统支配的,所以它管不到堆区,所以,如果A当中有处于堆区的属性或方法,浅复制是会自动跳过,并且会将它们与原有属性或方法绑定在同一个地址上。
怎么说呢?看栗子:
class A{
char *a_a;
char* changea_a();
};
A *a = new A();
A *b = a;
- 1
- 2
- 3
- 4
- 5
- 6
首先,初始化a的时候,对a_a进行了空间的分配(函数我就不写了),而后,将a浅复制给b,此时,a的字符串和b的字符串其实指向的是同一块地址。此时,如果通过b调用修改字符串的函数changea_a(),则a对应的字符串也将受到修改。
深复制
何为深复制?想必已经很明确了,就是显式定义的、复制构造函数。
当然,你就算显式定义了,也不一定就是深复制,可能定义出来的还是浅复制。
来看完整栗子:
#include<iostream>
#include<string>
using namespace std;
//工作经历类
class WorkExp {
private:
string WorkData;
string Company;
public:
WorkExp(){};
string getData() { return WorkData; }
void setData(string Data) { WorkData = Data; } string getCom() { return Company; }
void setCom(string Com) { Company = Com; }
WorkExp(WorkExp& wep) { WorkData = wep.WorkData;
Company = wep.Company;
}
};
//简历类
class Resume {
private:
string name;
string sex;
string age;
WorkExp *work;
public:
Resume(string name){
this->name = name;
work = new WorkExp();
}
//Resume(WorkExp *work) { this->work = work; }
Resume(Resume& res) {
name = res.name;
age = res.age;
sex = res.sex;
work = new WorkExp(*res.work); //这是关键点
//work = res.work;//写成这样就是浅复制
}
//设置个人信息
void SetPersonalInfo(string sex, string age) {
this->sex = sex;
this->age = age;
}
void SetWorkExp(string workData, string Company) {
work->setData(workData);
work->setCom(Company);
}
void show()
{
cout << "姓名:" << this->name << endl << "性别:"<<this->sex<<endl << "年龄:"<<this->age<< endl;
cout << "工作经历:" << work->getData() << " " << "工作公司:" << work->getCom() << endl;
}
};
int main()
{
Resume* a = new Resume("啊钒");
a->SetPersonalInfo("man","22");
a->SetWorkExp("2017 - 2021", "XX大学");
Resume b = *a;
b.SetPersonalInfo("girl", "26");
b.SetWorkExp("2021 - 2023", "AA公司");
a->show();
b.show();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
原型模式
讲完深浅复制,原型模式其实就很简单了。
文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。
原文链接:lion-wu.blog.csdn.net/article/details/106120316
- 点赞
- 收藏
- 关注作者
评论(0)