首页 > 代码库 > 第十七篇:复制控制( 上 ) --- 自定义复制函数
第十七篇:复制控制( 上 ) --- 自定义复制函数
前言
若要将a对象复制给b对象,编译器应当做何工作?C++初学者也许会直接说” a对象的成员复制给b对象的成员 “。在很多情况下,这种说法正确,事实上C++会给类定义一个默认的复制函数,它所做的工作也正是如此。但,下面问题来了:如果类的成员当中有指针,这种做法还行吗?本文将对这个问题作出实例分析。
一个典型错误示例
下面这个代码示例用来检验前言中所提到的问题:
1 #include <iostream> 2 #include <cstdlib> 3 #include <fstream> 4 #include <string> 5 6 using namespace std; 7 8 class A { 9 public:10 // 构造函数为指针成员开辟空间并赋初值011 A() {12 num_p = new int;13 *num_p = 0;14 }15 // 给指针所指对象赋值16 void setNum(int num) {17 *num_p = num;18 } 19 // 获取指针所指对象20 int getNum() const {21 int num = *num_p;22 return num;23 }24 private:25 int *num_p;26 };27 28 int main()29 {30 A a1;31 32 // 设置a1指针成员所指对象的值33 a1.setNum(1);34 // 调用系统自动合成的复制函数35 A a2 = a1;36 // 观察得出a1,a2的指针成员所指对象均为整数1。37 cout << "a1`s num: " << a1.getNum() << endl;38 cout << "a2`s num: " << a2.getNum() << endl;39 40 // 修改a1指针成员所指对象的值41 a1.setNum(2);42 // 观察得出不单a1的指针成员所指对象改了,a2的也跟着变了。 43 cout << "a1`s num: " << a1.getNum() << endl; 44 cout << "a2`s num: " << a2.getNum() << endl;45 46 return 0;47 }
运行结果:
我们可以观察到,当类中具有指针成员时,如果使用默认的复制函数,那么此后当某个对象修改了其指针成员所指对象,那么该类派生的其他对象的指针成员所指对象也会跟着改变。这显然不符合编程规范,下面我们将提出解决方案。
解决思路
既然系统自带的复制函数无法满足我们的要求,那么我们可以自定义一个以指定编译器在复制对象时的操作。
一个正确示例
下面这个代码给出了一个具体解决方案,复制函数启用时,拷贝指针所指对象,而不是指针本身:
1 #include <iostream> 2 #include <cstdlib> 3 #include <fstream> 4 #include <string> 5 6 using namespace std; 7 8 class A { 9 public:10 // 构造函数为指针成员开辟空间并赋初值011 A() {12 num_p = new int;13 *num_p = 0;14 }15 // 自定义复制函数 16 A(const A & a) {17 num_p = new int;18 *num_p = a.getNum();19 }20 // 给指针所指对象赋值21 void setNum(int num) {22 *num_p = num;23 } 24 // 获取指针所指对象25 int getNum() const {26 int num = *num_p;27 return num;28 }29 private:30 int *num_p;31 };32 33 int main()34 {35 A a1;36 37 // 设置a1指针成员所指对象的值38 a1.setNum(1);39 // 调用自定义的复制函数40 A a2=a1;41 // 观察得出a1,a2的指针成员所指对象均为整数1。42 cout << "a1`s num: " << a1.getNum() << endl;43 cout << "a2`s num: " << a2.getNum() << endl;44 45 // 修改a1指针成员所指对象的值46 a1.setNum(2);47 // 观察得出a1的指针成员所指对象改了,a2的没变。 48 cout << "a1`s num: " << a1.getNum() << endl; 49 cout << "a2`s num: " << a2.getNum() << endl;50 51 return 0;52 }
运行结果:
这一次,两个对象没有出现“ 相互干扰 ”了。
说明
1. 复制函数不单在A a = b的形式下启用,在作为函数参数传递时,生成容器时也会启用,这点要注意到。
2. 注意复制函数的原型( 形参为const引用且无返回 )
第十七篇:复制控制( 上 ) --- 自定义复制函数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。