建设信用卡网站,正规淘宝店铺交易平台,网站顶端图片素材,wordpress自动加载插件使用场景#xff1a;当需要构建多个相同的类对象时#xff0c;而且该类对象结构较为复杂#xff0c;如果每个都重新组织构建会很麻烦。 其实#xff0c;就是写一个拷贝构造函数#xff0c;或者写一个拷贝每个成员变量的clone()方法。 举例说明#xff1a;比如一个相亲网站… 使用场景当需要构建多个相同的类对象时而且该类对象结构较为复杂如果每个都重新组织构建会很麻烦。 其实就是写一个拷贝构造函数或者写一个拷贝每个成员变量的clone()方法。 举例说明比如一个相亲网站需要定义一个“男人”类可想而知描述清楚一个男人肯定需要很多属性吧比如姓名、身高、体重、职业、财产大致情况、联系电话、微信号、QQ号等。如果一个男人同时有多个相亲对象时每次都重新构建填写属性显然太麻烦所以类中需要定义一个拷贝的方法。
先写一个简单的类
#pragma once
#include QString
class singleMan
{
public:singleMan(QString name,double height,double weight,QString career,QString phoneNum);~singleMan();QString m_name;//姓名double m_height;//身高double m_weight;//体重QString m_career;//职业QString m_phoneNum;//电话};
#include singleMan.h
singleMan::singleMan(QString name, double height, double weight, QString career, QString phoneNum):m_name(name),m_height(height),m_weight(weight),m_career(career),m_phoneNum(phoneNum)
{
}singleMan::~singleMan()
{
}直接赋值打印出的内容也完全一样还需要写什么拷贝构造吗
singleMan sman(LaoWang, 178, 153, programmer, 19969961024);singleMan sman1 sman;cout sman: sman.m_name.toStdString() ; sman.m_phoneNum.toStdString() endl;cout sman1: sman1.m_name.toStdString() ; sman1.m_phoneNum.toStdString() endl; 这里c会自动创建一个默认的拷贝构造函数将成员变量中的值复制一次。但是当类中有指针类型成员变量时默认的构造函数仅仅把地址复制一份两个对象指向的是同一个内存地址对象销毁时会造成同一个内存被释放两次造成double free例子如下添加一个指针类型成员变量-近半年工资流水
singleman类中添加double* m_monthSalary指针成员变量
double* m_monthSalary nullptr;//近半年工资流水
类的析构中释放指针空间
singleMan::~singleMan()
{if (m_monthSalary!nullptr){delete m_monthSalary;m_monthSalary nullptr;}
} double salary[6] { 30000,30000,40000,50000,60000 };sman.m_monthSalary salary;singleMan sman2 sman;cout sman: sman.m_monthSalary[0] sman.m_monthSalary[1] sman.m_monthSalary[2] sman.m_monthSalary[3] endl;cout sman2: sman2.m_monthSalary[0] sman2.m_monthSalary[1] sman2.m_monthSalary[2] sman2.m_monthSalary[3] endl; 调用打印没问题但是程序结束后会报错 所以这里需要自己写一个拷贝构造函数实现中需要重新分配新的内存地址即所谓的深拷贝
//拷贝构造singleMan(const singleMan man);//这里要用引用引用做参数时可减少一次对象拷贝同时避免了循环拷贝构造问题
singleMan::singleMan(const singleMan man)
{m_career man.m_career;m_height man.m_height;m_name man.m_name;m_phoneNum man.m_phoneNum;m_weight man.m_weight;m_monthSalary new double[6];memcpy(m_monthSalary, man.m_monthSalary, 6 * sizeof(double*));
} double* salary new double[6];salary[0] 30000;salary[1] 30000;salary[2] 40000;salary[3] 50000;salary[4] 60000;salary[5] 65000;sman.m_monthSalary salary;singleMan sman2 sman;cout sman salary: sman.m_monthSalary endl;cout sman2 salary: sman2.m_monthSalary endl;cout sman: sman.m_monthSalary[0], sman.m_monthSalary[1] , sman.m_monthSalary[2] , sman.m_monthSalary[3] endl;cout sman2: sman2.m_monthSalary[0] , sman2.m_monthSalary[1] , sman2.m_monthSalary[2] , sman2.m_monthSalary[3] endl;此时上述问题貌似已经解决了但是在实际使用过程中会有这种用法将一个类对象赋值给另一个已经构造好的对象 singleMan sman3(LaoLi, 183, 160, programmer, 19969960512);sman3 sman;cout sman: sman.m_name.toStdString() ; sman.m_phoneNum.toStdString() endl;cout sman3: sman3.m_name.toStdString() ; sman3.m_phoneNum.toStdString() endl;cout sman salary: sman.m_monthSalary endl;cout sman3 salary: sman3.m_monthSalary endl;cout sman: sman.m_monthSalary[0] , sman.m_monthSalary[1] , sman.m_monthSalary[2] , sman.m_monthSalary[3] endl;cout sman3: sman3.m_monthSalary[0] , sman3.m_monthSalary[1] , sman3.m_monthSalary[2] , sman3.m_monthSalary[3] endl; 这时就不进入拷贝构造函数了而是进入了默认的赋值操作符函数中会有同样的问题这时需要写一个赋值操作符重载函数 //赋值运算符重载用新的对象的值全部替换原有项singleMan operator(const singleMan man);
singleMan singleMan::operator(const singleMan man)
{if (m_monthSalary ! nullptr){delete m_monthSalary;m_monthSalary nullptr;}m_career man.m_career;m_height man.m_height;m_name man.m_name;m_phoneNum man.m_phoneNum;m_weight man.m_weight;m_monthSalary new double[6];memcpy(m_monthSalary, man.m_monthSalary, 6 * sizeof(double*));return *this;
}
再次调用问题得到解决 最后由于拷贝构造函数中代码和赋值运算符代码几乎一致可以在拷贝构造函数中直接调研赋值运算符重载函数 singleMan::singleMan(const singleMan man)
{/*m_career man.m_career;m_height man.m_height;m_name man.m_name;m_phoneNum man.m_phoneNum;m_weight man.m_weight;m_monthSalary new double[6];memcpy(m_monthSalary, man.m_monthSalary, 6 * sizeof(double*));*/*this man;
} 如有问题欢迎指正
参考文献
【精选】C创建型模式-原型模式_c 原型模式-CSDN博客
4. 原型模式Prototype (yuque.com)