运算符重载提高

重载赋值运算符=

  1. 赋值运算符重载用于对象数据的复制
  2. operator= 必须重载为成员函数
  3. 重载函数原型为:
    类型 & 类名 :: operator= ( const 类名 & ) ;

在这里插入图片描述
结论:

  1. 先释放旧的内存
  2. 返回一个引用
  3. =操作符 从右向左
//obj3 = obj1;  // C++编译器提供的 等号操作 也属 浅拷贝
// obj4 = obj3 = obj1
//obj3.operator=(obj1)

Name& operator=(Name &obj1)
{
	//1 先释放obj3旧的内存
	if (this->m_p != NULL)
	{
		delete[] m_p;
		m_len = 0;
	}
	//2 根据obj1分配内存大小
	this->m_len = obj1.m_len;
	this->m_p = new char [m_len+1];
	
	//3把obj1赋值给obj3
	strcpy(m_p, obj1.m_p);
	return *this;
}

*为什么operator=返回一个reference to this ?

为了实现连续赋值,赋值操作符必须返回一个引用指向操作符的左侧实参。
这是你为class实现赋值操作符必须遵循的协议。
这个协议不仅适用于标准的赋值形式,也适用于+=、-=、*=等等。

注意,这只是一个协议。如果不遵循它,可能代码一样通过编译。
然而这份协议被所有内置类型和标准程序库所提供的类型如string、vector等所遵守。
因此除非你有一个标新立异的好理由,不然还是随众吧。

重载数组下标运算符 []

重载 [] 和 () 运算符:

  1. 运算符 [] 和 () 是二元运算符
  2. [] 和 () 只能用成员函数重载,不能用友元函数重载

重载下标运算符 []

[] 运算符用于访问数据对象的元素
重载格式 类型 类 :: operator[] ( 类型 ) ;

设 x 是类 X 的一个对象,则表达式:
x [ y ] 可被解释为 x . operator [ ] ( y )

在这里插入图片描述
在这里插入图片描述

重载函数调用符 ()

() 运算符用于函数调用
重载格式 类型 类 :: operator() ( 表达式表 ) ;

例1
设 x 是类 X 的一个对象,则表达式:
x ( arg1, arg2, … )
可被解释为 x . operator() (arg1, arg2, … )

//例2:用重载()运算符实现数学函数的抽象
#include <iostream>
class  F
  { public :  
        double  operator ( )  ( double x ,  double  y ) ;
  } ;
double  F :: operator ( )  ( double  x ,  double  y )
   { return   x * x + y * y ; }
void main ( )			
{ 
F  f  ;
f.getA();
  	cout << f ( 5.2 , 2.5 ) << endl ;  // f . operator() (5.2, 2.5)
}

比较普通成员函数
//例3  用重载()运算符实现 pk 成员函数
#include <iostream.h>
class  F
  { public :  
        double  memFun ( double x ,  double  y ) ;
  } ;
double  F :: memFun ( double  x ,  double  y )
   { return   x * x + y * y ; }
void main ( )			
{ 
F  f  ;
   	cout << f.memFun ( 5.2 , 2.5 ) << endl ;
}

指针运算符(*、->)重载

class Person{
public:
	Person(int param){
		this->mParam = param;
	}
	void PrintPerson(){
		cout << "Param:" << mParam << endl;
	}
private:
	int mParam;
};

class SmartPointer{
public:
	SmartPointer(Person* person){
		this->pPerson = person;
	}
	//重载指针的->、*操作符
	Person* operator->(){
		return pPerson;
	}
	Person& operator*(){
		return *pPerson;
	}
	~SmartPointer(){
		if (pPerson != NULL){
			delete pPerson;
		}
	}
public:
	Person* pPerson;
};

void test01(){
	
	//Person* person = new Person(100);
	//如果忘记释放,那么就会造成内存泄漏

	SmartPointer pointer(new Person(100));
	pointer->PrintPerson();
}

为什么不要重载&&和||操作符

理论知识:

  1. &&和||是C++中非常特殊的操作符
  2. &&和||内置实现了短路规则
  3. 操作符重载是靠函数重载来完成的
  4. 操作数作为函数参数传递
  5. C++的函数参数都会被求值,无法实现短路规则

内置版本的&&和||首先计算左边的表达式,如果这完全能够决定结果,就无需计算右边的表达式了–而且能够保证不需要。

class Complex{
public:
	Complex(int flag){
		this->flag = flag;
	}
	Complex& operator+=(Complex& complex){
		this->flag = this->flag + complex.flag;
		return *this;
	}
	bool operator&&(Complex& complex){
		return this->flag && complex.flag;
	}
public:
	int flag;
};
int main(){

	Complex complex1(0);
	Complex complex2(1);

	//原来情况,应该从左往右运算,左边为假,则退出运算,结果为假
	//这边却是,先运算(complex1+complex2),导致,complex1的flag变为complex1+complex2的值, complex1.a = 1
	// 1 && 1
	//complex1.operator&&(complex1.operator+=(complex2))
	if (complex1 && (complex1 += complex2)){   
		cout << "真!" << endl;
	}
	else{
		cout << "假!" << endl;
	}

	return EXIT_SUCCESS;
}

根据内置&&的执行顺序,我们发现这个案例中执行顺序并不是从左向右,而是先右猴左,这就是不满足我们习惯的特性了。由于complex1 += complex2先执行,导致complex1 本身发生了变化,初始值是0,现在经过+=运算变成1,1 && 1输出了真。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值