C++ 类的聚集和浅拷贝与深拷贝

1.类的聚集
类的成员中含有某类的指针,这种类叫类的聚集。又被称为“远程所有权”(remote ownership)。

该类的对象的数据将存放在对象外边,对象中只存放数据的地址。数据可以是数组、对象等。



2.浅拷贝与深拷贝

浅拷贝

–实现对象间数据元素的一一对应复制。这是拷贝构造函数的本能。当数据元素是指针的时候,则出问题。

深拷贝

–当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指的对象(区域)进行复制。

对象的浅拷贝

[cpp]  view plain copy
  1. //对象的浅拷贝  
  2. #include<iostream>  
  3. using namespace std;  
  4. class Point  
  5. {   
  6. public:  
  7.     Point()  
  8.     { X=Y=0; cout<<"Default Constructor called.\n";}  
  9.     Point(int xx,int yy)  
  10.     { X=xx; Y=yy; cout<< "Constructor called.\n"; }  
  11.     ~Point() { cout<<"Destructor called.\n"; }  
  12.     int GetX() {return X;}  
  13.     int GetY() {return Y;}  
  14.     void Move(int x,int y){ X=x; Y=y; }  
  15. private:  
  16.     int X,Y;  
  17. };  
  18.   
  19. class ArrayOfPoints     //这个类叫“控制类”  
  20. {   
  21. public:  
  22.     ArrayOfPoints(int n) // 按照指示创建指定个数的对象  
  23.     {   
  24.         numberOfPoints = n;  
  25.         points = new Point[n];   
  26.     }  
  27.     ~ArrayOfPoints()  
  28.     {   
  29.         cout<<"Deleting..."<<endl;  
  30.         numberOfPoints=0;   
  31.         delete[] points;   
  32.     }  
  33.     Point& Element(int n)  
  34.     {   
  35.         return points[n];   
  36.     }  
  37. private:  
  38.     Point *points; //类内只保存对象数组的首址  
  39.     int numberOfPoints; //对象的个数  
  40. };  
  41.   
  42.   
  43. void main()  
  44. {  
  45.     int number;  
  46.     cout << "Please enter the number of points:";  
  47.     cin>>number;  
  48.     ArrayOfPoints pointsArray1(number);   
  49.     pointsArray1.Element(0).Move(5,10);   
  50.     pointsArray1.Element(1).Move(15,20);  
  51.     //对象的浅拷贝  
  52.     ArrayOfPoints pointsArray2(pointsArray1);  
  53.     //输出对象的值  
  54.     cout<<"Copy of pointsArray1:"<<endl;  
  55.     cout<<"Point_0 of array2: "  
  56.     <<pointsArray2.Element(0).GetX()  
  57.     <<", "<<pointsArray2.Element(0).GetY()<<endl;  
  58.     cout<<"Point_1 of array2: "  
  59.     <<pointsArray2.Element(1).GetX()  
  60.     <<", "<<pointsArray2.Element(1).GetY()<<endl;  
  61.       
  62.     //对象1的值改变同时也会改变对象2的值  
  63.     pointsArray1.Element(0).Move(25,30);  
  64.     pointsArray1.Element(1).Move(35,40);  
  65.   
  66.     //输出对象的值  
  67.     cout<<"After the moving of pointsArray1:"<<endl;  
  68.     cout<<"Point_0 of array2: "  
  69.     <<pointsArray2.Element(0).GetX()  
  70.     <<", "<<pointsArray2.Element(0).GetY()<<endl;  
  71.     cout<<"Point_1 of array2: "  
  72.     <<pointsArray2.Element(1).GetX()  
  73.     <<", "<<pointsArray2.Element(1).GetY()<<endl;  
  74. }  
运行结果:

Please enter the number of points:2
Default Constructor called.
Default Constructor called.
Copy of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
After the moving of pointsArray1:
Point_0 of array2: 25, 30
Point_1 of array2: 35, 40
Deleting...
Destructor called.
Destructor called.
Deleting...(同一块空间被释放了两次)

接下来程序出现异常,也就是运行错误。

对象的深拷贝

[cpp]  view plain copy
  1. //对象的深拷贝  
  2. #include<iostream>  
  3. using namespace std;  
  4. class Point  
  5. {   
  6. public:  
  7.     Point()  
  8.     { X=Y=0; cout<<"Default Constructor called.\n";}  
  9.     Point(int xx,int yy)  
  10.     { X=xx; Y=yy; cout<< "Constructor called.\n"; }  
  11.     ~Point() { cout<<"Destructor called.\n"; }  
  12.     int GetX() {return X;}  
  13.     int GetY() {return Y;}  
  14.     void Move(int x,int y){ X=x; Y=y; }  
  15. private:  
  16.     int X,Y;  
  17. };  
  18.   
  19.   
  20. class ArrayOfPoints     //这个类叫“控制类”  
  21. {   
  22. public:  
  23.     ArrayOfPoints(int n) // 按照指示创建指定个数的对象  
  24.     {   
  25.         numberOfPoints = n;  
  26.         points = new Point[n];   
  27.     }  
  28.     //不能用默认的拷贝构造函数,必须重写了  
  29.     ArrayOfPoints(ArrayOfPoints& pointsArray);  
  30.   
  31.     ~ArrayOfPoints()  
  32.     {   
  33.         cout<<"Deleting..."<<endl;  
  34.         numberOfPoints=0;   
  35.         delete[] points;   
  36.     }  
  37.     Point& Element(int n)  
  38.     {   
  39.         return points[n];   
  40.     }  
  41. private:  
  42.     Point *points; //类内只保存对象数组的首址  
  43.     int numberOfPoints; //对象的个数  
  44. };  
  45.   
  46. //拷贝构造函数  
  47. ArrayOfPoints::ArrayOfPoints(ArrayOfPoints& pointsArray)  
  48. {   
  49.     numberOfPoints = pointsArray.numberOfPoints;  
  50.     //申请新的空间  
  51.     points=new Point[numberOfPoints];  
  52.     for (int i=0; i<numberOfPoints; i++)  
  53.     //把值拷贝过来  
  54.     points[i].Move(pointsArray.Element(i).GetX(),  
  55.     pointsArray.Element(i).GetY());  
  56. }  
  57.   
  58.   
  59. void main()  
  60. {  
  61.     int number;  
  62.     cout << "Please enter the number of points:";  
  63.     cin>>number;  
  64.     ArrayOfPoints pointsArray1(number);   
  65.     pointsArray1.Element(0).Move(5,10);   
  66.     pointsArray1.Element(1).Move(15,20);  
  67.     cout << "test\n";  
  68.     //对象的深拷贝  
  69.     ArrayOfPoints pointsArray2(pointsArray1);  
  70.   
  71.     cout<<"Copy of pointsArray1:"<<endl;  
  72.     cout<<"Point_0 of array2: "  
  73.     <<pointsArray2.Element(0).GetX()  
  74.     <<", "<<pointsArray2.Element(0).GetY()<<endl;  
  75.     cout<<"Point_1 of array2: "  
  76.     <<pointsArray2.Element(1).GetX()  
  77.     <<", "<<pointsArray2.Element(1).GetY()<<endl;  
  78.   
  79.     //深拷贝对象2的值不会因对象1的值改变而改变  
  80.     pointsArray1.Element(0).Move(25,30);  
  81.     pointsArray1.Element(1).Move(35,40);  
  82.   
  83.   
  84.     cout<<"After the moving of pointsArray1:"<<endl;  
  85.     cout<<"Point_0 of array2: "  
  86.     <<pointsArray2.Element(0).GetX()  
  87.     <<", "<<pointsArray2.Element(0).GetY()<<endl;  
  88.     cout<<"Point_1 of array2: "  
  89.     <<pointsArray2.Element(1).GetX()  
  90.     <<", "<<pointsArray2.Element(1).GetY()<<endl;  
  91. }  
运行结果:

Please enter the number of points:2
Default Constructor called.
Default Constructor called.
Default Constructor called.
Default Constructor called.
Copy of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
After the moving of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
Deleting...
Destructor called.
Destructor called.
Deleting...
Destructor called.
Destructor called.
Press any key to continue

使用动态存储分配的类要重写拷贝构造函数




设计并实现一个动态整型数组Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。 设计并实现一个动态整型数组Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值