C++类_运算符的重载
在 C++11 中,运算符重载允许你为自定义类型重新定义运算符的行为,使得自定义类型的对象能够像内置类型一样使用运算符。下面为你详细介绍 C++11 中运算符重载的相关内容,包含基本概念、语法、可重载的运算符、注意事项以及示例。
基本概念
运算符重载是一种特殊的函数,它使用运算符作为函数名。通过运算符重载,你可以让自定义类型的对象使用诸如 +
、-
、*
、/
等运算符,以实现自定义的操作逻辑。
语法
运算符重载函数的定义语法如下:
返回类型 operator 运算符 (参数列表) {// 函数体
}
这里的 operator
是关键字,运算符
代表要重载的运算符,参数列表
则依据运算符的特性和需求来确定。
可重载的运算符
C++ 中大多数运算符都能被重载,但也有部分运算符不能重载,比如 .
、.*
、::
、?:
等。常见可重载的运算符如下,函数格式的声明参考附录。
- 算术运算符:
+
、-
、*
、/
、%
- 关系运算符:
==
、!=
、>
、<
、>=
、<=
- 逻辑运算符:
&&
、||
、!
- 位运算符:
&
、|
、^
、~
、<<
、>>
- 赋值运算符:
=
、+=
、-=
、*=
、/=
、%=
等 - 自增自减运算符:
++
、--
- 函数调用运算符:
()
- 下标运算符:
[]
注意事项
- 不能改变运算符的优先级和结合性:运算符重载只是重新定义运算符的操作逻辑,不会改变其原有的优先级和结合性。
- 至少有一个操作数是自定义类型:运算符重载函数的参数中至少要有一个是自定义类型的对象,这样才能实现对自定义类型的操作。
- 避免过度重载:运算符重载应该遵循合理的语义,避免让代码变得难以理解。
示例
1. 重载 +
运算符
#include <iostream>class Complex {
private:double real;double imag;
public:Complex(double r = 0, double i = 0) : real(r), imag(i) {}// 重载 + 运算符Complex operator+(const Complex& other) const {return Complex(real + other.real, imag + other.imag);}void display() const {std::cout << real << " + " << imag << "i" << std::endl;}
};int main() {Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.display();return 0;
}
在这个例子里,Complex
类代表复数,通过重载 +
运算符实现了两个复数的相加。
2. 重载 ==
运算符
#include <iostream>class Point {
private:int x;int y;
public:Point(int a = 0, int b = 0) : x(a), y(b) {}// 重载 == 运算符bool operator==(const Point& other) const {return (x == other.x) && (y == other.y);}
};int main() {Point p1(1, 2);Point p2(1, 2);Point p3(3, 4);if (p1 == p2) {std::cout << "p1 and p2 are equal." << std::endl;}if (p1 != p3) {std::cout << "p1 and p3 are not equal." << std::endl;}return 0;
}
此示例中,Point
类代表二维平面上的点,通过重载 ==
运算符来判断两个点是否相等。
3. 重载 ++
运算符(前置和后置)
#include <iostream>class Counter {
private:int value;
public:Counter(int v = 0) : value(v) {}// 前置 ++ 运算符重载Counter& operator++() {++value;return *this;}// 后置 ++ 运算符重载Counter operator++(int) {Counter temp = *this;++(*this);return temp;}int getValue() const {return value;}
};int main() {Counter c(5);// 前置 ++Counter c1 = ++c;std::cout << "After pre-increment: " << c1.getValue() << std::endl;// 后置 ++Counter c2 = c++;std::cout << "After post-increment: " << c2.getValue() << std::endl;return 0;
}
在这个示例中,Counter
类代表计数器,分别重载了前置和后置 ++
运算符。前置 ++
返回引用,后置 ++
通过一个 int
类型的占位参数来区分,返回临时对象。
附录
运算符分类 | 运算符 | 函数参数格式 | 说明 |
---|---|---|---|
算术运算符 | + | 成员函数:返回类型 operator+(const 类名& other) const; 非成员函数: 返回类型 operator+(const 类名& lhs, const 类名& rhs); | 实现加法操作,成员函数的 other 表示右操作数,非成员函数的 lhs 和 rhs 分别表示左操作数和右操作数。 |
- | 成员函数:返回类型 operator-(const 类名& other) const; 非成员函数: 返回类型 operator-(const 类名& lhs, const 类名& rhs); | 实现减法操作。 | |
* | 成员函数:返回类型 operator*(const 类名& other) const; 非成员函数: 返回类型 operator*(const 类名& lhs, const 类名& rhs); | 实现乘法操作。 | |
/ | 成员函数:返回类型 operator/(const 类名& other) const; 非成员函数: 返回类型 operator/(const 类名& lhs, const 类名& rhs); | 实现除法操作。 | |
% | 成员函数:返回类型 operator%(const 类名& other) const; 非成员函数: 返回类型 operator%(const 类名& lhs, const 类名& rhs); | 实现取模操作。 | |
关系运算符 | == | 成员函数:bool operator==(const 类名& other) const; 非成员函数: bool operator==(const 类名& lhs, const 类名& rhs); | 判断两个对象是否相等,返回 bool 类型。 |
!= | 成员函数:bool operator!=(const 类名& other) const; 非成员函数: bool operator!=(const 类名& lhs, const 类名& rhs); | 判断两个对象是否不相等,返回 bool 类型。 | |
> | 成员函数:bool operator>(const 类名& other) const; 非成员函数: bool operator>(const 类名& lhs, const 类名& rhs); | 判断左操作数是否大于右操作数,返回 bool 类型。 | |
< | 成员函数:bool operator<(const 类名& other) const; 非成员函数: bool operator<(const 类名& lhs, const 类名& rhs); | 判断左操作数是否小于右操作数,返回 bool 类型。 | |
>= | 成员函数:bool operator>=(const 类名& other) const; 非成员函数: bool operator>=(const 类名& lhs, const 类名& rhs); | 判断左操作数是否大于等于右操作数,返回 bool 类型。 | |
<= | 成员函数:bool operator<=(const 类名& other) const; 非成员函数: bool operator<=(const 类名& lhs, const 类名& rhs); | 判断左操作数是否小于等于右操作数,返回 bool 类型。 | |
逻辑运算符 | && | 成员函数:bool operator&&(const 类名& other) const; 非成员函数: bool operator&&(const 类名& lhs, const 类名& rhs); | 实现逻辑与操作,返回 bool 类型。但不建议重载逻辑与和逻辑或运算符,因为它们的短路特性可能会丢失。 |
`|| | 成员函数:`bool operator||(const 类名 & other) const; 非成员函数: bool operator||(const 类名 & lhs, const 类名 & rhs);` | `实现逻辑或操作,返回 bool 类型。同样不建议重载,避免丢失短路特性。 | |
! | 成员函数:bool operator!() const; 非成员函数: bool operator!(const 类名& obj); | 实现逻辑非操作,返回 bool 类型。 | |
位运算符 | & | 成员函数:返回类型 operator&(const 类名& other) const; 非成员函数: 返回类型 operator&(const 类名& lhs, const 类名& rhs); | 实现按位与操作。 |
`| | `成员函数:` 返回类型 operator|(const 类名 & other) const; 非成员函数: 返回类型 operator|(const 类名 & lhs, const 类名 & rhs);` | 实现按位或操作。 | |
^ | 成员函数:返回类型 operator^(const 类名& other) const; 非成员函数: 返回类型 operator^(const 类名& lhs, const 类名& rhs); | 实现按位异或操作。 | |
~ | 成员函数:返回类型 operator~() const; 非成员函数: 返回类型 operator~(const 类名& obj); | 实现按位取反操作。 | |
<< | 成员函数:返回类型 operator<<(int shift) const; 非成员函数: 返回类型 operator<<(const 类名& obj, int shift); | 实现左移操作。 | |
>> | 成员函数:返回类型 operator>>(int shift) const; 非成员函数: 返回类型 operator>>(const 类名& obj, int shift); | 实现右移操作。 | |
赋值运算符 | = | 成员函数:类名& operator=(const 类名& other); | 实现赋值操作,通常返回自身的引用。 |
+= | 成员函数:类名& operator+=(const 类名& other); | 实现复合赋值加法操作,返回自身的引用。 | |
-= | 成员函数:类名& operator-=(const 类名& other); | 实现复合赋值减法操作,返回自身的引用。 | |
*= | 成员函数:类名& operator*=(const 类名& other); | 实现复合赋值乘法操作,返回自身的引用。 | |
/= | 成员函数:类名& operator/=(const 类名& other); | 实现复合赋值除法操作,返回自身的引用。 | |
%= | 成员函数:类名& operator%=(const 类名& other); | 实现复合赋值取模操作,返回自身的引用。 | |
&= | 成员函数:类名& operator&=(const 类名& other); | 实现复合赋值按位与操作,返回自身的引用。 | |
`|=` | 成员函数:` 类名 & operator|=(const 类名 & other);` | 实现复合赋值按位或操作,返回自身的引用。 | |
^= | 成员函数:类名& operator^=(const 类名& other); | 实现复合赋值按位异或操作,返回自身的引用。 | |
<<= | 成员函数:类名& operator<<=(int shift); | 实现复合赋值左移操作,返回自身的引用。 | |
>>= | 成员函数:类名& operator>>=(int shift); | 实现复合赋值右移操作,返回自身的引用。 | |
自增自减运算符 | ++ (前置) | 成员函数:类名& operator++(); | 前置自增运算符,返回自身的引用。 |
++ (后置) | 成员函数:类名 operator++(int); | 后置自增运算符,int 为占位参数,返回临时对象。 | |
-- (前置) | 成员函数:类名& operator--(); | 前置自减运算符,返回自身的引用。 | |
-- (后置) | 成员函数:类名 operator--(int); | 后置自减运算符,int 为占位参数,返回临时对象。 | |
函数调用运算符 | () | 成员函数:返回类型 operator()(参数列表); | 使对象可以像函数一样被调用。 |
下标运算符 | [] | 成员函数:返回类型& operator[](索引类型 index); 常成员函数: const 返回类型& operator[](索引类型 index) const; | 实现对象的下标访问,返回引用以便可以进行读写操作。常成员函数用于 const 对象,返回 const 引用。 |
其他运算符 | -> | 成员函数:返回类型 operator->(); | 重载箭头运算符,通常用于智能指针类,返回一个指针或者一个重载了 -> 运算符的对象。 |
, | 成员函数:返回类型 operator,(const 类名& other); 非成员函数: 返回类型 operator,(const 类名& lhs, const 类名& rhs); | 重载逗号运算符,不建议轻易重载,因为逗号运算符的语义较为固定。 | |
new 、delete | 静态成员函数:void* operator new(size_t size); 静态成员函数: void operator delete(void* ptr); 静态成员函数: void* operator new[](size_t size); 静态成员函数: void operator delete[](void* ptr); | 重载内存分配和释放运算符,new 用于分配内存,delete 用于释放内存。new[] 和 delete[] 用于数组的内存分配和释放。 |