C++运算符重载

一、操作符函数

定义:在C++中,编译器有能力把一个由数据、对象和操作符共同组成的表达式,解释为对一个全局或成员函数的调用。该全局或成员函数被称为操作符函数,通过重定义操作符函数,可以实现针对自定义类型的运算法则,并使之与内置类型一样参与各种表达式。

一般,C++中每个操作符(+、-、<<、[]……)都有自己的使用方法,但是有时由于数据结构的不同,我们需要对某一个操作符的方法进行有必要的修改,如坐标点的对应相加、对象属性的打印等问题,根据实际需要对操作数的方法进行重新定义,以满足需求!

//Point是一个二维坐标点类
Point p1(2,5);
Point p2(3,7);
Point p3(6,2);

p3 = p1 + p2;

这样的‘+’运算符是无效的,原来的方法不适用,但我们可以根据实际情况编写对应相加的‘+’运算符函数,就可以满足实际要求

二、双目操作符表达式

1、成员函数:形如L#R双目操作符表达式,将被编译器解释为 L.operator#(R)

a-b+c == a.operator-(b).operator+(c)

2、全局函数:形如L#R的双目操作符表达式,将被编译器解释为 ::operator#(L,R)

a-(b+c) == ::operator-(a,::operator+(b,c))

三、单目操作符表达式

1、 成员函数 :形如#O或O#的单目操作表达式,将被编译器解释为 O.operator#(),唯一的操作数是调用对象。

2、全局函数:形如#O或O#的单目操作表达式,将被编译器解释为 ::operator#(O),唯一的操作数是调用对象。

四、典型的双目运算符重载

1、成员函数:返回值类型 operator 运算符 (第二个参数);第一个参数以this指针隐式传入

//注意:原对象的值不变,要产生一个临时的对象,所以返回值不能引用返回
Point operator /+-*%|^& (Point& that)
{	
    Point t; // 会调用无参构造
	t.x = x / that.x;
	t.y = y / that.y;
	return t; // 不能返回局部对象的引用,否则会出现悬空引用
}
bool operator > < >= <= == != || && (Point& that)
{
	......	
}
Point& operator += -= *= /=  (Point& that)
{
    ......
    return *this;	
}
        //(局部)运算符重载&&
	void operator && (Point& that)
	{
		cout << "====jubu====" << endl;
	}
	//(局部)运算符重载+=
	Point& operator += (Point& that)
	{
		x += that.x;
		y += that.y;
		return *this;
	}
	//(局部)运算符重载<=
	bool operator <= (Point& that)
	{
		if(x <= that.x) return true;
		else return false;
	}
	//(局部)运算符重载+
	Point operator + (Point& that)
	{
		Point t;
		t.x = x + that.x;
		t.y = y + that.y;
		return t;
	}
	//(局部)运算符重载-
	Point operator - (Point& that)
	{
		Point t;
		t.x = x - that.x;
		t.y = y - that.y;
		return t;
	}
	//(局部)运算符重载/
	Point operator / (Point& that)
	{
		Point t;
		t.x = x / that.x;
		t.y = y / that.y;
		return t;
	}

2、全局函数:返回值类型 operator 运算符 (第一个参数,第二个参数)

可能会访问到参数的私有成员:
                   把成员变成公开,但会破坏类的封闭性;
                   把全局函数声明为友元(友元不是成员);
                   不能在友元函数中直接访问成员变量。

Point operator + (Point& a,Point& b)
{
	Point t(a.x+b.x,a.y+b.y);
	return t;
}

五、典型的单目运算符重载

1、成员函数:自增运算符、自减运算符

        Point& operator ++ (void)//默认前++
	{
		x++;
		y++;
		return *this;
	}
	Point operator ++ (int)//后++
	{
		Point p = *this;
		x++;
		y++;
		return p;
	}
	Point& operator -- (void)//
	{
		x--;
		y--;
		return *this;
	}
	Point operator -- (int)//
	{
		Point p =*this;
		x--;
		y--;
		return p;
	}

2、全局函数:自增运算符、自减运算符

Point& operator ++ (Point& a)
{
	a.x++;
	a.y++;
	return a;
}
Point operator ++ (Point& a,int)
{
	Point p = a;
	a.x++;
	a.y++;
	return p;
}

六、输入、输出运算符重载

输入、输出运算符不能重载为成员函数,只能是友元。

        //运算符重载<<只能是全局重载
	friend ostream& operator << (ostream& os,Point& that)
	{
		return os << that.x << " " << that.y;
	}
	//运算符重载>>只能是全局重载
	friend istream& operator >> (istream& is,Point& that)
	{
		return is >> that.x >> that.y;
	}

七、特殊的运算符的重载

    [] 下标运算符,可以把对象当作数组来使用
    () 函数运算符,可以把对象当作函数来使用
    -> 成员访问运算符,可以把对象当作指针来使用
    * 解引用运算符,可以把对象当作指针来使用

        Point& operator [](int i)
	{
		x += i;
		y += i;
		return *this;
	}
	Point& operator ()(int x,int y)
	{
		this->x += x;
		this->y += y;
		return *this;
	}
	Point* operator -> (void)
	{
		return this;
	}

new/delete 也可以进行重载,但不建议使用
        new会自动调用重载的new函数再构造函数
        delete会先调用析构再调用重载的delete函数

        void* operator new (unsigned int size)
	{
		cout << "----new----" << endl;
		return malloc(size);
	}
	void operator delete (void* p)
	{
		cout << "----delete----" << endl;
		free(p);
	}

只有极个别的运算符的重载对于对象来说是有意义(>>,<<)
        常考的运算符重载:前++/--,后++/--

八、运算符重载的一些限制

1、不能重载的运算符
        :: 作用域限定符
        . 成员访问运算
        .* 成员指针解引用
        ?: 三目运算符
        sizeof 字节长度运算符
        typeid 类型信息操作符

2、运算符的重载改变不了运算符的优先级

3、无法改变运算符的操作个数 

4、无法发明新的运算符

5、重载运算符要注意运算符的一致性,不要改变运算符默认的运算规则

6、运算符的重载是为了方便使用、增强可读,不应该成功卖弄的工具

作业:使用C++的语法实现单向链表,并重载[]、<<(参考代码:https://gitee.com/ZhongShengXueXi/codes/ayd8uibc2mgnezh7sf0j423

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值