【C++】运算符重载 Operator Overload

本文介绍了C++中的运算符重载,通过重载运算符可以使类支持如加法等算术操作。内容包括如何通过全局函数和成员函数实现运算符重载,以及对前置++和后置++的区别处理。还提到了一些不能重载的运算符和特定运算符必须作为成员函数重载的情况,如赋值运算符、下标运算符等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

运算符重载 Operator Overload

可以为运算符增加一些新的功能

class Point {
private:
	int m_x;
	int m_y;
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	void display() {
		cout << "(" << m_x << ", " << m_y << ")" << endl;
	}
};
  • 直接将两个Point类相加得到新的点

    比如Point p3 = p1 + p2;,这样就要使用运算符重载,因为平常加号两端不可以是Point类的

class Point {
friend Point operator+(const Point &, const Point &);
private:
	int m_x;
	int m_y;
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	void display() {
		cout << "(" << m_x << ", " << m_y << ")" << endl;
	}
};

Point operator+(const Point &p1, const Point &p2) {
    return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
// 1. 传入的Point类最好加上引用,避免产生不必要的中间变量
// 2. 最好加上const,这样const和非const对象都可以传入,接受范围大一些
// 3. 加上const和引用后,友元函数传入参数也要加const和引用

int main() {
    Point p1(10, 20);
    Point p2(20, 30);
    Point p3 = p1 + p2;
    // 相当于 Point p3 = operator+(p1, p2);
}

为运算符加号’+'增加新的功能,返回一个point。

这样是把运算符重载函数放在类外面,如果放到里面变成一个成员函数,就只要传入一个Point对象就可以了,并且也不需要声明友元函数了。

class Point {
private:
	int m_x;
	int m_y;
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	void display() {
		cout << "(" << m_x << ", " << m_y << ")" << endl;
	}
    // 最左边的const为了防止返回的Point被赋值 (p1 + p2 = p3是不允许的)
    // 最右边的const为了const返回值又可以调用operator+ (但要允许p1 + p2 + p3)
 	const Point operator+(const Point &point) const{
    	return Point(this->m_x + point.m_x, this->m_y + point.m_y);
        // 或者省略this
        // return Point(m_x + point.m_x, m_y + point.m_y);
	}    
};
int main() {
    Point p1(10, 20);
    Point p2(20, 30);
    p1 + p2;
    // 相当于 p1.operator+(p2);
}

所以,全局函数、成员函数都支持运算符重载

返回值最好是个const对象,返回值不允许再被赋值,但加上const之后就不允许连续相加了。所以要再加一个const。

  • 再实现一下+=
class Point {
private:
	int m_x;
	int m_y;
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	void display() {
		cout << "(" << m_x << ", " << m_y << ")" << endl;
	}
    // 最左边的const为了防止返回的Point被赋值
    // 最右边的const为了const返回值又可以调用operator+
 	const Point operator+(const Point &point) const{
    	return Point(this->m_x + point.m_x, this->m_y + point.m_y);
        // 或者省略this
        // return Point(m_x + point.m_x, m_y + point.m_y);
	}    
    
    // 为了能够再赋值,返回是当前对象而不是地址,所以返回*this而不是this,返回this就是返回当前对象的地址
    // 加引用是为了防止产生中间变量,如果将类里面返回的函数拿到另一个函数中用,会重新拷贝构造出一个新的对象
 	Point &operator+=(const Point &point) {
        m_x += point.m_x;
        m_y += point.m_y;
        return *this;
	}     
};
int main() {
    Point p1(10, 20);
    Point p2(20, 30);
    p1 += p2;
    // 相当于 p1.operator+=(p2);
    
    (p1 += p2) = Point(50, 60);
    // p1 = p1 + p2;
    // p1 = Point(50, 60);
}
  • 完成-p1的操作(单目运算符)
const Point operator-() const {
    return Point(-m_x, -m_y);
}     
  • 前置++和后置++
// 前置++, ++p
Point &operator++() {
    m_x++;
    m_y++;
    return *this;
}

// 后置++(加一个int,只能是int,无论内部是什么样),p++
const Point operator++(int) {
    Point old(m_x, m_y);
    m_x++;
    m_y++;
    return old;
}
  • 注意:

    • 前置++可以被赋值,后置++不可以

      比如:

      ++a = 20; // 可以
      (a++) = 20; // 不可以
      

      所以前置++返回是一个对象的引用

      后置++返回的是const Point

  • 左移,实现 cout << p1 << endl;

    // 不能写 void operator<<()
    // 因为<<不是单目运算符
    // 下面这个写法相当于
    // p1 << 10; 
    // p1.operator<<(10)
    void operator<<(int a) {
        
    }
    // 但我们要实现的是cout << p1 << endl; 传入point
    // 它就不能是成员函数,必须是全局函数,所以要将其加入Point的友元函数
    // cout也是对象,是ostream对象(output stream)
    // 如果要实现cout << p1 << p2;
    // 就要返回cout,这很重要!
    // 但cout的返回值是不能再被赋值的,可以把这个函数放到private中,这样就不会再被赋值
    ostream &operator<<(ostream &cout, const Point& point) {
    	cout << "(" << point.m_x << ", " << point.m_y << ")";
    	return cout;
    }
    
  • 右移,实现输入

    // input stream -> istream
    istream &operator>>(istream &cin, Point &point) {
    	cin >> point.m_x;
    	cin >> point.m_y;
    	return cin;
    }
    
  • 调用父类的运算符重载函数

    image-20220116164531112
  • 运算符重载注意点

    • 有些运算符不可以被重载

      • 对象成员访问运算符:.
      • 域运算符:::
      • 三目运算符:?:
      • sizeof
    • 有些运算符只能写在类里面重载为成员函数,比如

      • 赋值运算符:=
      • 下标运算符:[]
      • 函数运算符:()
      • 指针访问运算符:->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值