【C++面向对象】C++中运算符重载的两种方式

        我们知道在C++中可以通过重载运算符的方式,使类实现类似于基本类型的运算符操作,如+、-、*、/等等。本文介绍这种重载运算符的两种方法。

我们先自定义一个类,来作为本次研究的对象:

class Integer
{
	public:
		Integer(){}
		Integer(int i):m_i(i){}
		void get_val()
		{
			cout<<m_i<<endl;
		}
	private:
		int m_i;
};
        我们先看一下这个类,类中只包含一个私有的成员变量m_i,然后分别定义了无参和有参两种构造函数,并定义了一个函数get_val用于打印m_i的值来验证结果。
为了演示,我们分别重载运算符"+"和"-",通过运算符重载我们要实现的效果是:
Integet a,b;
Integer c= a + b;
c = a - b;

        首先我们用第一种方法, 通过成员函数的形式来实现运算符重载。最简单的重载形式如下:

Integer operator+(Integer that)
{
	Integer i;
	i.m_i=this->m_i+that.m_i;
	return i;	
}
       我们在main函数中进行调用,发现已经达到了目的:

int main()
{
	Integer a(10),b(20);
	Integer c=a+b;
	c.get_val();
	return 0;
}
运行结果:

[Hyman@Hyman-PC Integer]$ g++ integer.cpp 
[Hyman@Hyman-PC Integer]$ ./a.out 
30
那么是不是这样就算重载成功了呢?

“当然不是!”

“是的话我还在这废什么话?”


这种重载函数虽然能够达到重载的效果,但是还存在三个隐患,作为一个追去完美的程序员,我们必须指出来:


1、参数采用Integer that,在运行时势必会利用Integer的拷贝构造函数构建参数副本,如果Integer定义的很大的话,造成了资源的不必要浪费,所以这里要改成引用的形式--Integer& that,但是仅仅利用引用还是不够的,因为如果b的类型是const Integer 呢?Integer c=a+b;就会编译出错,因为const 类型的引用,是不能传给非const类型的引用的,所以,上述操作符重载函数就应该改成这样:

Integer operator+(const Integer& that)
{
	Integer i;
	i.m_i=this->m_i+that.m_i;
	return i;	
}


2、如果a改成const Integer的形式,同样也无法调用,原因和第一条一样,Integer operator+(const Integer& that)中隐含包含的this指针不是const类型的,因此不能被const Integer类型的对象使用,这次把a改成const Integer,编译下,出现下面的错误:

[Hyman@Hyman-PC Integer]$ g++ integer.cpp 
integer.cpp: In function ‘int main()’:
integer.cpp:28: 错误:将‘const Integer’作为‘Integer Integer::operator+(const Integer&)’的‘this’实参时丢弃了类型限定

怎么解决?当然是把this指针也生命成const类型,那么现在函数原型就变成下面这副鬼样子:

Integer operator+(const Integer& that) const
{
	Integer i;
	i.m_i=this->m_i+that.m_i;
	return i;	
}


3、最后一条,先问各位看官(如果有的话,没有就是我自言自语了),见过下面这种基本类型的加法运算吗:

(2+3)=4

可能有童鞋会说,这是什么玩意儿?解释一下,我的意思就是说,大家有见过把一个基本类型的对象赋值给一个+操作符返回的对象吗?

答案肯定是见过!

”在哪见得?“

”刚在这见得“。

但是我们自定义的这个类就支持这种操作,我们在main函数中这样调用:

int main()
{
	const Integer a(10);
	const Integer b(20);
	Integer d(100);
	Integer c=a+b;
	(a+b)=d;
	//c.get_val();
	return 0;
}
然后我们进行编译,华丽丽的通过了:

[Hyman@Hyman-PC Integer]$ g++ integer.cpp 
[Hyman@Hyman-PC Integer]$ 
       这当然不可以,我们重载操作符的目的就是想让我们自己定义的类向基本类型一样符合我们对操作符操作的理解,而支持这样奇怪的运算方式,显然超出了我们的理解,所以这也要改!怎么改?很简单,在返回值前面也加一个const,这样整个+的重载函数就变成了这样:
const Integer operator+(const Integer& that) const
{
	Integer i;
	i.m_i=this->m_i+that.m_i;
	return i;	
}
现在还是编译上面main函数中的代码就会报错:

[Hyman@Hyman-PC Integer]$ g++ integer.cpp 
integer.cpp: In function ‘int main()’:
integer.cpp:30: 错误:将‘const Integer’作为‘Integer& Integer::operator=(const Integer&)’的‘this’实参时丢弃了类型限定
但是这正是我们需要的。

这样,就完成了对+的重载,完美!!

好接下来,介绍下另外一种利用友元函数进行重载的方式,附上代码,不再多说,各位看官自己体会去吧:

const Integer operator-(const Integer& a,const Integer& b)
{
	Integer i;
	i.m_i=a.m_i-b.m_i;
	return i;
}
最后附上整个文章的代码:

#include<iostream>
using namespace std;

class Integer
{
	public:
		Integer(){}
		Integer(int i):m_i(i){}
		const Integer operator+(const Integer& that) const;
		void get_val()
		{
					cout<<m_i<<endl;
		}
	private:
		int m_i;
		friend const Integer operator-(const Integer& a,const Integer& b);
};

const Integer Integer::operator+(const Integer& that) const
{
	Integer i;
	i.m_i=this->m_i+that.m_i;
	return i;
}

const Integer operator-(const Integer& a,const Integer& b)
{
	Integer i;
	i.m_i=a.m_i-b.m_i;
	return i;
}

int main()
{
	const Integer a(10);
	const Integer b(20);
	Integer d(100);
	Integer c=a+b;
	d=a-b;
	//(a+b)=d;
	c.get_val();
	d.get_val();
	return 0;
}







  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C++运算符重载的规则如下: 1. 只能重载C++已有的运算符,不能重载成员运算符“.”、指针运算符“*”、作用域运算符“::”等少数几个运算符。 2. 重载后的运算符必须至少有一个操作数是用户自定义的类型。 3. 重载后的运算符不能改变原有的操作数个数。 4. 重载后的运算符不能改变原有的操作数类型。 5. 重载后的运算符不能改变原有的优先级和结合性。 6. 重载后的运算符不能改变原有的语法结构。 实现运算符重载方式是通过定义一个成员函数或非成员函数来实现。对于成员函数,重载的运算符作为函数名,不需要指定返回类型,也不需要指定参数列表,因为操作数已经隐式地作为函数的调用者和参数传递进来了。对于非成员函数,重载的运算符作为函数名,需要指定返回类型和参数列表,其至少有一个参数是用户自定义的类型。 以下是一个实现运算符重载的例子,假设我们定义了一个名为Complex的复数类,需要实现加法运算符的重载: ```c++ class Complex { public: Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} Complex operator+(const Complex& c) const { return Complex(real + c.real, imag + c.imag); } private: double real; double imag; }; ``` 在上面的例子,我们通过定义一个名为operator+的成员函数来实现加法运算符的重载。该函数的参数是一个常量引用,表示另一个复数对象,返回值是一个新的Complex对象,表示两个复数对象相加的结果。在函数体内,我们通过访问成员变量real和imag来实现复数的加法运算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值