C++运算符重载

C++运算符重载

系统的运算符需要符合特定的数据类型才可以使用,举个例子,默认情况下两个类对象p1,p2不能相加。我们可以通过运算符重载,使p1+p2可以相加,相加的结果则是由运算符重载函数的实现来定义。

运算符重载需要的关键字:operator

:本文省略了为对象属性赋值的过程。

加号重载

创建一个类

class person
{
    public:
    int m_a;
    int m_b;
};

想实现 p3.m_a=p1.m_a+p2.m_a; p3.m_b=p1.m_b+p2.m_b

这时可以使用运算符重载,使最终形式为p3=p1+p2。

有两种重载方式:

  1. 在成员函数中重载
  2. 在全局函数中重载
1.在成员函数实现重载。
class person
{
    public:
    int m_a;
    int m_b;
  person operator+(person&p)
  {
      person temp;
      temp.m_a=this->m_a+p.m_a;
      temp.m_b=this->m_b+p.m_b;
      return temp;
  }
};
.......
    
person p1;
person p2;
....
person p3=p1+p2;

2.在全局函数中实现
    person operator+(person&p,person&b)
{
    person temp;
    temp.m_a=p.m_a+b.m_a;
    temp.m_b=p.m_b+b.m_b;
    return temp;
};

...
    
person p1;//注:这些操作在函数中写。
person p2;

...
    
person p3=p1+p2;
左移运算符重载

系统内置的类型,可以用<<简便地输出,而如果想输出一个对象的值,不能简单地用 <<对象,这时可以用左移运算符重载。

左移运算符重载不可以在成员函数中实现,只能在全局函数中实现

在全局函数中实现:

class person
{
  public:  
    int m_a;
    int m_b;
};
...

ostream& operator<<(ostream&cout,person&p)//步1
{
    cout<<"p.m_a="<<p.m_a<<"p.m_b="<<p.m_b;//步2
    return cout; //步3
}
//步1:左移运算符重载用到cout,cout属于ostream。用到person对象。两个都用引用。
//步2:这步中的cout是引用名cout,不是平时的cout。<<是平时的<<,还不是重载的<<。所以&cout可以换成&其他东西
//步3:返回cout,对应着函数类型ostream&,从可以不断的使用<<  例如:下面的在cout<<p1后面加上<<endl;
因为<<前面必须是ostream(即cout)

void teat01()
{
    person p1;
    p1.name="tom";
    cout<<p1<<endl;//这步输出tom。
}

前置递增&后置递增运算符重载

递增运算符的重载用类内函数实现,不能用全局函数,递减同理。

class person
{
public:
	person()
	{
		ma = 10;
		mb = 20;
	}
	person& operator++()//前置递增
	{
		this->ma++;
		this->mb++;
		return *this;//this指向某一对象的地址,*this解引用,得到该对象,所以前面可以用person&接收。而且必须用引用的方式,否则如果遇上++++p1就行不通了,因为如果只是person而不是引用,则第一次++后返回的是一个拷贝的对象,不再是p1递增。
	}
	person& operator++(int)//后置递增,用int占位符,区别于前置递增
	{
		this->ma++;
		this->mb++;
		return *this;
	}
	int ma;
	int mb;
};


ostream& operator<<(ostream& cout, person& p)
{
	cout << p.ma <<"  "<< p.mb;
	return cout;
}
void test01()
{
	person p1;
	++p1;
	cout << p1 << endl;
}

递减于递增同理。

赋值运算符重载

赋值运算符同样写在类内。

:赋值运算符重载和拷贝构造函数一样,需要考虑堆区的问题。和深拷贝浅拷贝类似。

class person
{
public:
	person()
	{
		ma = 10;
		mb = 20;
		m_age=new int(30);
	}
	person& operator=(person& p)//赋值运算符重载
	{
		ma = p.ma;
		mb = p.mb;
		if (m_age != NULL)//判断该指针是否为空,有则释放
		{
			delete m_age;
		}
		m_age = new int(*p.m_age);//然后这步和深拷贝方法类似。
		return *this;//函数类型为person&以及返回类型为对象本身,这样可以使用类似p1=p2=p3的操作;
	}
	~person()
	{
		if (m_age != NULL)//有new就要注意析构函数中是否需要释放。
		{
			delete m_age;
			m_age = NULL;
		}
	}
	int ma;
	int mb;
	int* m_age;
};
void test01()
{
	person p1;
	//++p1
	person p2;//步1
	p2 = p1;//步2
	cout << p1 << endl;
	cout << p2 << endl;
}

:上面的test01中,如果把步1步2换成

person p2=p1;

那么对于当前的程序来说会崩掉,因为这样运用的其实是拷贝构造函数,而不是赋值运算符重载函数。此时的拷贝函数是浅拷贝,所以会崩掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值