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

时间:2022-07-06 19:48:05
1.类的聚集
类的成员中含有某类的指针,这种类叫类的聚集。又被称为“远程所有权”(remote ownership)。

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

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


2.浅拷贝与深拷贝

浅拷贝

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

深拷贝

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

对象的浅拷贝

//对象的浅拷贝
#include<iostream>
using namespace std;
class Point
{ 
public:
	Point()
	{ X=Y=0; cout<<"Default Constructor called.\n";}
	Point(int xx,int yy)
	{ X=xx; Y=yy; cout<< "Constructor called.\n"; }
	~Point() { cout<<"Destructor called.\n"; }
	int GetX() {return X;}
	int GetY() {return Y;}
	void Move(int x,int y){ X=x; Y=y; }
private:
	int X,Y;
};

class ArrayOfPoints     //这个类叫“控制类”
{ 
public:
	ArrayOfPoints(int n) // 按照指示创建指定个数的对象
	{ 
		numberOfPoints = n;
		points = new Point[n]; 
	}
	~ArrayOfPoints()
	{ 
		cout<<"Deleting..."<<endl;
		numberOfPoints=0; 
		delete[] points; 
	}
	Point& Element(int n)
	{ 
		return points[n]; 
	}
private:
	Point *points; //类内只保存对象数组的首址
	int numberOfPoints; //对象的个数
};


void main()
{
	int number;
	cout << "Please enter the number of points:";
	cin>>number;
	ArrayOfPoints pointsArray1(number); 
	pointsArray1.Element(0).Move(5,10); 
	pointsArray1.Element(1).Move(15,20);
	//对象的浅拷贝
	ArrayOfPoints pointsArray2(pointsArray1);
	//输出对象的值
	cout<<"Copy of pointsArray1:"<<endl;
	cout<<"Point_0 of array2: "
	<<pointsArray2.Element(0).GetX()
	<<", "<<pointsArray2.Element(0).GetY()<<endl;
	cout<<"Point_1 of array2: "
	<<pointsArray2.Element(1).GetX()
	<<", "<<pointsArray2.Element(1).GetY()<<endl;
	
	//对象1的值改变同时也会改变对象2的值
	pointsArray1.Element(0).Move(25,30);
	pointsArray1.Element(1).Move(35,40);

	//输出对象的值
	cout<<"After the moving of pointsArray1:"<<endl;
	cout<<"Point_0 of array2: "
	<<pointsArray2.Element(0).GetX()
	<<", "<<pointsArray2.Element(0).GetY()<<endl;
	cout<<"Point_1 of array2: "
	<<pointsArray2.Element(1).GetX()
	<<", "<<pointsArray2.Element(1).GetY()<<endl;
}
运行结果:

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...(同一块空间被释放了两次)

接下来程序出现异常,也就是运行错误。
C++ 类的聚集和浅拷贝与深拷贝

对象的深拷贝

//对象的深拷贝
#include<iostream>
using namespace std;
class Point
{ 
public:
	Point()
	{ X=Y=0; cout<<"Default Constructor called.\n";}
	Point(int xx,int yy)
	{ X=xx; Y=yy; cout<< "Constructor called.\n"; }
	~Point() { cout<<"Destructor called.\n"; }
	int GetX() {return X;}
	int GetY() {return Y;}
	void Move(int x,int y){ X=x; Y=y; }
private:
	int X,Y;
};


class ArrayOfPoints     //这个类叫“控制类”
{ 
public:
	ArrayOfPoints(int n) // 按照指示创建指定个数的对象
	{ 
		numberOfPoints = n;
		points = new Point[n]; 
	}
	//不能用默认的拷贝构造函数,必须重写了
	ArrayOfPoints(ArrayOfPoints& pointsArray);

	~ArrayOfPoints()
	{ 
		cout<<"Deleting..."<<endl;
		numberOfPoints=0; 
		delete[] points; 
	}
	Point& Element(int n)
	{ 
		return points[n]; 
	}
private:
	Point *points; //类内只保存对象数组的首址
	int numberOfPoints; //对象的个数
};

//拷贝构造函数
ArrayOfPoints::ArrayOfPoints(ArrayOfPoints& pointsArray)
{ 
	numberOfPoints = pointsArray.numberOfPoints;
	//申请新的空间
	points=new Point[numberOfPoints];
	for (int i=0; i<numberOfPoints; i++)
	//把值拷贝过来
	points[i].Move(pointsArray.Element(i).GetX(),
	pointsArray.Element(i).GetY());
}


void main()
{
	int number;
	cout << "Please enter the number of points:";
	cin>>number;
	ArrayOfPoints pointsArray1(number); 
	pointsArray1.Element(0).Move(5,10); 
	pointsArray1.Element(1).Move(15,20);
	cout << "test\n";
	//对象的深拷贝
	ArrayOfPoints pointsArray2(pointsArray1);

	cout<<"Copy of pointsArray1:"<<endl;
	cout<<"Point_0 of array2: "
	<<pointsArray2.Element(0).GetX()
	<<", "<<pointsArray2.Element(0).GetY()<<endl;
	cout<<"Point_1 of array2: "
	<<pointsArray2.Element(1).GetX()
	<<", "<<pointsArray2.Element(1).GetY()<<endl;

    //深拷贝对象2的值不会因对象1的值改变而改变
	pointsArray1.Element(0).Move(25,30);
	pointsArray1.Element(1).Move(35,40);


	cout<<"After the moving of pointsArray1:"<<endl;
	cout<<"Point_0 of array2: "
	<<pointsArray2.Element(0).GetX()
	<<", "<<pointsArray2.Element(0).GetY()<<endl;
	cout<<"Point_1 of array2: "
	<<pointsArray2.Element(1).GetX()
	<<", "<<pointsArray2.Element(1).GetY()<<endl;
}
运行结果:

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

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


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