<>从简历投递的故事说起

本来今天不打算用别人的故事了,但是吧,技术这东西,枯燥无味,如果我们连学个东西干嘛用都不知道,那学来干嘛?所以我觉得,这个入门应用场景是很重要的。

今天我去面试了,我需要在简历上填写我的项目经验,格式都是一水的:”XXXX - XX - XX,做过XX项目,任XX职务,收获XXXX“···
很显然,这可以用一个项目经验类来实现。

但是这一水的项目经验下来,每个经验都要初始化一个实例,成何体统?
好在我项目没过几个,还是可以赏心悦目的。

这时,就可以考虑让一个实例,有多个分身,每个分身再通过类方法修改其成员属性,岂不美哉?那要怎么分身?分身乏术啊,如果不熟悉类的复制构造函数的话。

<>复制构造函数

知道构造函数的人一般都知道,构造函数分为”深构造“和”浅构造“。如果不知道的话,也不用去别的地方找了,一般来说结果不会很满意,因为我找过了。

<>浅复制

看这样一个栗子:
class A{}; A *a = new A(); A *b = a;

像这样把一个对象直接传给另一个对象,一般情况下就是浅复制,是系统默认提供的一种构造方式。但是这种构造方式有什么潜在风险呢?因为是系统支配的,所以它管不到堆区,所以,如果A当中有处于堆区的属性或方法,浅复制是会自动跳过,并且会将它们与原有属性或方法绑定在同一个地址上。

怎么说呢?看栗子:
class A{ char *a_a; char* changea_a(); }; A *a = new A(); A *b = a;

首先,初始化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; }
<>原型模式

讲完深浅复制,原型模式其实就很简单了。

技术
©2019-2020 Toolsou All rights reserved,
华为认证HCIA-AI人工智能NOI2019 游记消息质量平台系列文章|全链路排查篇过拟合和欠拟合的形象解释Unity 场景异步加载(加载界面的实现)Faster RCNN系列算法原理讲解(笔记)纽约年轻人计划“重新占领华尔街”:维护散户利益用C++跟你聊聊“原型模式” (复制/拷贝构造函数)初识python之技巧总结篇中级JAVA程序员应该掌握的数据结构知识