C++ 运算符重载详细介绍
C++ 运算符重载是指允许为用户定义的类型赋予运算符新的行为,从而使得自定义类型可以像内置类型一样使用运算符。通过运算符重载,可以提高代码的可读性和一致性。
一、运算符重载的基本规则
- 运算符重载的形式
- 运算符重载可以是成员函数或全局函数。
- 对于某些运算符,必须用成员函数实现(如
=、[]、()、->)。 - 对于对称运算符(如
+、-等),建议用全局函数实现。
- 不可重载的运算符
以下运算符无法重载:::(作用域解析运算符).(成员访问运算符).*(成员指针访问运算符)sizeof(类型大小运算符)typeid(类型信息运算符)
- 返回值和参数
- 运算符的返回值类型和参数数量应尽量符合预期。
- 对于链式操作(如
+=),建议返回引用。
二、使用成员函数重载的原因
- 访问类的私有和保护成员
- 成员函数可以直接访问类的私有和保护成员,因此重载运算符时无需额外设置。
- 适用于需要直接操作当前对象的运算符。
- 单目(unary)运算符
- 对于单目运算符(如
++、--、!等),成员函数更直观,因为它们只作用于当前对象。
- 对于单目运算符(如
- 需要绑定左操作数为当前对象
- 如果运算符的左操作数必须是当前类的对象(如赋值运算符
=),则必须用成员函数重载。 - 如
=、[]、()和->这些运算符只能用成员函数实现。
- 如果运算符的左操作数必须是当前类的对象(如赋值运算符
- 支持链式操作
- 某些运算符(如
=和+=)需要返回*this的引用以支持链式操作。通过成员函数可以更方便地实现。
示例:重载=运算符
- 某些运算符(如
class MyClass {
private:
int value;
public:
MyClass(int v = 0) : value(v) {
}
// 重载赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
value = other.value;
}
return *this;
}
};
三、使用全局函数重载的原因
- 对称性要求
- 对于二元运算符(如
+、-、*等),全局函数能够保持左右操作数的对称性。 - 如果左操作数不是类的对象(如
3 + myObject),则必须使用全局函数。
- 对于二元运算符(如
- 增强灵活性
- 全局函数可以使运算符作用于类的对象与非类的对象(如内置类型)的组合。
- 通过友元声明,仍然可以访问类的私有成员。
- 扩展性
- 全局函数可以更好地扩展已有类,而无需修改类的定义。
示例:重载+运算符
- 全局函数可以更好地扩展已有类,而无需修改类的定义。
#include <iostream>
class MyClass {
private:
int value;
public:
MyClass(int v = 0) : value(v) {
}
// 友元声明
friend MyClass operator+(const MyClass& lhs, const MyClass& rhs);
void display() const {
std::cout << value << std::endl