C++——复制构造函数和赋值运算符

对于Point类

显然是将b的坐标值赋值给a的坐标

Point a,b;
a = b;

看下一个demo:

TextFile a, b;
a.Open( "FILE1.DAT" );
b.Open( "FILE2.DAT" );
b = a;

前面的代码可能表示“将 FILE1.DAT 的内容复制到 FILE2.DAT”,也可能表示“忽略 FILE2.DAT 并使 b 成为 FILE1.DAT 的另一个句柄”。 

这里的歧义需要自己去实现 复制构造函数和复制赋值运算符 来达到想要的效果。

一般的:

复制构造函数:T(const T& x);

复制赋值运算符:T & operator=(const T & x);

如果不声明复制构造函数,编译器将为你生成 member-wise 复制构造函数。 如果不声明复制赋值运算符,编译器将为你生成 member-wise 复制赋值运算符。

对于复制构造函数,需要知道:何时调用和有何功能

何时调用:

新建一个对象并将其初始化为同类现有对象

扫描二维码关注公众号,回复: 3981464 查看本文章

表现形式有:

other是一个T类的对象

①T x(other);

②T x = other;

③T x = T(other);

④T *x = new T(other);

说明:

②和③:可以直接创建T类x对象,也可以创建一个临时对象将其成员的值赋给x

④创建匿名对象,x是其指针。

由于按值传递对象调用复制构造函数,因此应该按引用传递对象。这样可以节省调用构造函数的时间以及存储新对象的空间。

一、如果没有实现复制构造函数,那么系统有隐式复制构造函数 实现的是 对象的”浅拷贝”

如果遇到成员变量是指针,那么两者的指针指向位置相同。

当类调用析构函数时,会释放同一个地址,导致程序崩溃。

二、为了避免上述问题,解决方案是实现显式复制构造函数

新开辟一个相同大小的空间,利用内存(或字符串)拷贝给新开辟的空间。该方法也成“深拷贝”

三、一般的,如果类中包含了使用new初始化的指针成员,需要实现复制构造函数,反之则使用默认复制构造函数。

赋值运算符的功能和何时调用

一、首先初始化一个对象T x;

x = other; //other是T类对象

这时候调用了赋值运算符函数

与复制构造函数会遇到的问题相同:数据受损。

解决方法与前面类似。

总结:复制构造函数在对象初始化的时候调用,之后用到“=”赋值运算符的时候调用赋值函数

贴上demo:

#include <iostream>  
#include <string>  
using namespace std;  

class Rect
{
public:
	Rect()//默认构造函数
	{
		_m_byte = NULL;
		memset(_byte, 0, sizeof(_byte));
	}
	Rect(int x, int y, int width, int height, char * byte, char * m_byte)//普通构造
		: _x(x), _y(y), _width(width), _height(height)
	{	
		strcpy(_byte, byte);
		_m_byte = new char[strlen(m_byte) + 1];//开辟空间记得+1防止数组越界
		strcpy(_m_byte, m_byte);
	}
	Rect(const Rect& other)//复制构造函数
	{
		strcpy(_byte, other._byte);
		_m_byte = new char[strlen(other._m_byte) + 1];
		strcpy(_m_byte, other._m_byte);
	}
	Rect& operator=(const Rect & other)//赋值运算符函数
	{
		if(this == &other)    //先进行判定是否相同的对象
			return *this;
		
		if(_m_byte)            //判断是否开辟过空间
			delete []_m_byte;
			
		strcpy(_byte, other._byte);
		_m_byte = new char[strlen(other._m_byte) + 1];
		strcpy(_m_byte, other._m_byte);
		return *this;

	}
	~Rect()    //析构函数 释放new出来的_m_byte 防止内存泄露
	{
		_x = 0;
		_y = 0;
		_width = 0;
		_height = 0;
		memset(_byte, 0, sizeof(_byte));
		delete []_m_byte;
		_m_byte = NULL;
	}
/********************************************************************************/
/*偷懒就直接写成共有成员了,一般是私有变量,使用get(),或set()方法提取或设置成员变量的值*/
/********************************************************************************/
	int _x;
	int _y;
	int _width;
	int _height;
	char _byte[100];
	char *_m_byte;
private:
	
};

int main()  
{  

	Rect r(1,1,1,1,"123","234");//调用普通构造
	Rect r2 = r;                //调用复制构造函数
	Rect r3;                    //调用默认构造
	r3 = r;                    //调用赋值运算符函数
	cout << string(r._m_byte) << endl;
	cout << string(r2._m_byte) << endl;
	cout << string(r3._m_byte) << endl;

	system("pause");
}  

猜你喜欢

转载自blog.csdn.net/u012198575/article/details/83179820