C++必会语法之拷贝构造函数和运算符重载

目录

1.拷贝构造函数

拷贝构造函数的特征

2.运算符重载

用法

注意:


1.拷贝构造函数

首先讲讲为什么祖师爷为什么会在C++,设计拷贝构造函数,直接上代码。

class data
{
public:
	data( )
	{
		_a = (int*)malloc(sizeof(int) * 4);
	}
	~data( )
	{
		free(_a);
	}

private:
	int* _a;
};


int main()
{
	data d1;
	data d2 = d1;
	return 0;
}

这里为什么会报错呢?为什么C语言结构体这么拷贝就不会报错呢。

问题出就出在,析构函数上了,把d1值拷贝给d2,d1._a和d2._a是指向同一块空间的,d1生命周期结束后会调用析构函数把_a的空间释放,d2的生命周期结束的时还会把_a的空间再次释放一遍,这时候就出大问题了,所以就有了拷贝构造函数来解决这个问题。

拷贝构造函数的特征

1.只有单个形参,该形参是对类类型对象的引用(一般常用const修饰),在用已存
在的类类型对象创建新对象时由编译器自动调用。
2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,
因为会引发无穷递归调用
class data
{
public:
	data()
	{
		_year = 2004;
		_month = 12;
		_day = 26;
	}
	data(const data& d)//正确写法
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void printf()
	{
		cout << _year << '/' << _month << '/' <<_day<< endl;
	}
	//data(const data d)//错误写法
	//{
	//	_year = d._year;
	//	_month = d._month;
	//	_day = d._day;
	//}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	data d1;
	d1.printf();
	data d2(d1);//把d1拷贝给d2
	d2.printf();
	return 0;
}

如果这里data(const data d)为什么会出现无限递归。

因为传值传参,需要把原来的数据拷贝一份,自定义类型拷贝,又需要调用构造拷贝函数。

3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按
字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝
4. 类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请 时,则拷贝构造函数是一定要写的,否则就是浅拷贝,浅拷贝就会出现,析构函数的问题。
class data
{
public:
	data()
	{
		_year = 2004;
		_month = 12;
		_day = 26;
	}
	
	void printf()
	{
		cout << _year << '/' << _month << '/' <<_day<< endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	data d1;
	d1.printf();
	data d2(d1);//把d1拷贝给d2
	d2.printf();
	return 0;
}

2.运算符重载

运算符重载设计的目的就是为了增加代码的可读性

就像自定义类型是没办法比较大小的,例如日期类想要比较两个日期的大小,这个时候不同人写的函数名字就千奇百怪,什么样子的都有,要是是直接可以用">","<"比较该多好,这个是时候运算符重载就出现了。

用法

函数名字为:关键字operator后面接需要重载的运算符符号
函数原型:返回值类型  operator 操作符(参数列表)

注意:

不能通过连接其他符号来创建新的操作符:比如operator@
重载操作符必须有一个类类型参数
用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐
藏的this,调用时真实的写法应该是d1.operator<(&d1,d2)
class date
{
  public:
  bool operator>(const &date)  
   {
     if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month > d._month)
	{
		return true;
	}
	else if (_year == d._year && d._month == _month && _day > d._day)
	{
		return true;
	}
	return false;
   }

  private:
   int _year:
   int _month;
   int _day;
};

int main()
{
  date d1;
  date d2;
 if(d1>d2)
   {
    cout<<"hello word"<<endl;
   }
  retrun 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值