一、 什么是运算符重载?
运算符重载是 C++ 中的一种功能,它允许用户定义的类或数据类型重新定义或扩展运算符的行为,使运算符能够作用于用户定义的对象。
二、 通俗解释
在 C++ 中,运算符(如 +
, -
, *
, =
等)默认只能对内置类型(如 int
, float
)进行操作。
运算符重载允许用户通过特殊的函数定义,让运算符也能处理自定义类型(如类或结构体)。
例如:
- 默认情况下,
+
只能用来加两个整数:3 + 5
。 - 运算符重载后,
+
可以用来加两个对象(如ComplexNumber
类对象)。
三、运算符重载的目的
- 让自定义类型(如类和结构体)与内置类型一样,可以使用运算符进行运算或比较。
- 使代码更简洁直观,提高程序的可读性和可维护性。
四、运算符重载的规则
-
不能重载的运算符:
::
(作用域运算符).*
(成员指针运算符)sizeof
(计算对象大小)typeid
(类型识别运算符).
(成员访问运算符)
-
运算符重载不会改变运算符的优先级和结合性。
-
运算符重载不能引入新的运算符,只能重载已有的运算符。
-
不能改变运算符的操作数个数:
- 单目运算符:例如
-
(负号)。 - 双目运算符:例如
+
,*
,==
。
- 单目运算符:例如
-
运算符重载可以作为类的成员函数或友元函数,具体情况如下:
- 成员函数:左操作数必须是当前类对象。
- 友元函数:适用于左操作数不是当前类对象的情况。
五、重载运算符
运算符重载是通过特殊的函数实现的,这个函数名以 operator
开头,后面跟要重载的运算符。
1.运算符重载的实现方式
1.1 运算符重载作为类的成员函数
1.1.1语法格式:
ReturnType operator 运算符 (参数列表) {//ReturnType是运算符重载针对的数据类型// 重载运算符的逻辑
}
1.1.2 特点:
- 左侧操作数必须是当前类的对象。(关于左操作数的解释下面会有具体的扩展哈)
- 右侧操作数通过参数传递(如果是双目运算符)。
1.1.3 代码实例:重载 +
运算符(成员函数):计算两个复数的加法结果,并返回一个新的复数对象。(复数用对象表示,在对象的内部将复数的虚部和实部用成员变量来表示,即这里的一个Complex对象实例就是一个复数,这个对象里的real就是这个对象的实部,imag就是这个对象的虚部)
#include <iostream>
using namespace std;class Complex {int real, imag;public://构造一个结构体Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 + 运算符Complex operator+(const Complex& other) {return Complex(real + other.real, imag + other.imag);
//这里的other.real指的是其他的要跟当下的对象的real相加的实部(这里代码可以看做real是c1的虚部,other.real是c2的虚部)
//这里的other.imag指的是其他的要跟当下的对象的imag相加的实部(这里代码可以看做imag是c1的虚部,other.imag是c2的虚部)}void display() {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(3, 4), c2(1, 2);Complex c3 = c1 + c2; // 调用重载的 + 运算符//创建了一个新的对象c3,利用Complex对象+重载运算符将c1,c2对象的虚部和实部对应的相加给c3(c1,c2的实部相加给c3的实部,c1,c2的虚部相加给c3的虚部)c3.display();return 0;
}
1.1.4 解释:
1.other
是什么?
在运算符重载函数中:
Complex operator+(const Complex& other) {return Complex(real + other.real, imag + other.imag);
}
-
other
是重载+
运算符函数的 参数。 - 它代表
+
运算符右侧的对象。
例如:
Complex c1(3, 4), c2(1, 2);
Complex c3 = c1 + c2;
在表达式 c1 + c2
中:
c1
是左操作数,它是调用operator+
的对象(this
指针隐式传递)。c2
是右操作数,它作为参数other
传递给operator+
函数。
2. other.real
和 other.imag
是什么?
other
是一个 Complex
类型的对象,它具有 real
和 imag
两个成员变量(实部和虚部)。
other.real
:表示other
对象的 实部。other.imag
:表示other
对象的 虚部。
3.执行流程解析
1.创建对象 c1
和 c2
:
Complex c1(3, 4);
Complex c2(1, 2);
-
c1
的real = 3
,imag = 4
。 c2
的real = 1
,imag = 2
。
2.调用 c1 + c2:
Complex c3 = c1 + c2;
- 这行代码触发了 运算符重载函数
operator+
。 - 在函数
operator+
中:this->real
和this->imag
代表左操作数c1
的实部和虚部。other
是右操作数c2
。other.real
和other.imag
代表c2
的实部和虚部。
3.具体计算过程:
return Complex(real + other.real, imag + other.imag);
-
real + other.real
→3 + 1 = 4
(计算新的实部)。 imag + other.imag
→4 + 2 = 6
(计算新的虚部)。- 返回一个新的
Complex
对象,real = 4
,imag = 6
。
4.输出结果:
- 调用
display()
函数输出c3
的值:4 + 6i
5.整个流程的梳理:
6.在主函数部分:operator+
函数是编译器自动调用的
- 当你在代码中使用
+
运算符 作用于两个对象 时,编译器会自动去寻找并调用重载的operator+
函数。 - 前提是你必须在类中提供
operator+
函数的重载定义。 - 出发operator的具体流程:(截图来自ChatGTP)
operator+
函数的调用等价写法- 在表达式
c1 + c2
中,实际调用的是:
- 在表达式
c1.operator+(c2);
- 解释:
- 左操作数调用
operator+
,右操作数作为参数传入。计算相加结果,返回一个新对象。 c1
是调用operator+
函数的对象。c2
是参数other
。- 所以
c1 + c2
的行为与下面的代码等价:
- 左操作数调用
Complex c3 = c1.operator+(c2);
如果没有重载 +
运算符会发生什么?
如果你没有定义 operator+
,编译器不知道如何处理两个 Complex
对象的 +
运算,程序会报错。如:
error: no match for ‘operator+’ (operand types are ‘Complex’ and ‘Complex’)
1.1.5补充:多个对象调用运算符重载:
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 + 运算符Complex operator+(const Complex& other) {//括号内的参数表示指传入的参数是Complex型的数据并且传入参数是不可动的,是常对象,other表示这是运算符重载的右操作数return Complex(real + other.real, imag + other.imag);}void display() {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(3, 4), c2(1, 2), c3(2, 3);// 连续相加Complex c4 = c1 + c2 + c3; // 触发两次 operator+,(c1+c2)触发一次operator,(c1+c2)的结果再加一次c3有触发一次operatorc4.display(); // 输出 6 + 9ireturn 0;
}
/*
输出:
6+9i
*/
1.2 运算符重载作为友元函数
语法格式:
friend ReturnType operator 运算符 (参数列表);
//如:
//friend Complex operator+(……)
//friend Complex operator-(……)
特点:
- 左侧操作数可以是非当前类的对象。
- 通常用于重载需要两个不同类型操作数的运算符(如输入输出运算符
<<
和>>
)。
示例:重载 +
运算符(友元函数)
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 友元函数重载 +friend Complex operator+(const Complex& c1, const Complex& c2);void display() {cout << real << " + " << imag << "i" << endl;}
};// 友元函数实现
//类外补充一下:友元函数的格式 函数返回类型 友元函数名(友元函数参数)
//这里的友元函数名必须要是(operator+),表示重载+运算符,这是C++的语法规定
Complex operator+(const Complex& c1, const Complex& c2) {return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() {Complex c1(3, 4), c2(1, 2);Complex c3 = c1 + c2; // 调用重载的 + 运算符c3.display();return 0;
}
2. 单目运算符的重载
单目运算符(如 -
, ++
, --
)只需要一个操作数。
成员函数形式(单目运算符)
ReturnType operator 运算符 () {// 重载逻辑
}
代码实例:1.重载 -
运算符
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 - 运算符Complex operator-() {return Complex(-real, -imag);}void display() {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(-3, -4); // 创建一个复数对象 c1,实部 = 3,虚部 = 4Complex c2 = -c1; // 调用重载的 - 运算符cout << "Original Complex number: ";c1.display();cout << "Negated Complex number: ";c2.display();return 0;
}
2.代码示例:重载前置 ++
和 --
运算符
#include <iostream>
using namespace std;class Counter {int value;public:Counter(int v = 0) : value(v) {}// 重载前置 ++ 运算符Counter& operator++() {++value; // 先增加return *this; // 返回自身引用}// 重载前置 -- 运算符Counter& operator--() {--value; // 先减少return *this; // 返回自身引用}void display() const {cout << "Value: " << value << endl;}
};int main() {Counter c(10);++c; // 调用前置 ++c.display(); // 输出 11--c; // 调用前置 --c.display(); // 输出 10return 0;
}
3. 代码示例:重载后置 ++
和 --
运算符(后置 ++
和 --
需要一个 int 参数 作为区分标志。)
#include <iostream>
using namespace std;class Counter {int value;public:Counter(int v = 0) : value(v) {}// 重载后置 ++ 运算符Counter operator++(int) {//后置 ++ 和 -- 需要一个 int 参数 作为区分标志。Counter temp = *this; // 保存当前值value++; // 增加return temp; // 返回之前的值}// 重载后置 -- 运算符Counter operator--(int) {//后置 ++ 和 -- 需要一个 int 参数 作为区分标志。Counter temp = *this; // 保存当前值value--; // 减少return temp; // 返回之前的值}void display() const {cout << "Value: " << value << endl;}
};int main() {Counter c(10);c++; // 调用后置 ++c.display(); // 输出 11c--; // 调用后置 --c.display(); // 输出 10return 0;
}
3. 双目运算符的重载
双目运算符(如 +
, -
, *
, ==
)需要两个操作数。
成员函数形式(双目运算符)
ReturnType operator 运算符 (const Type& other) {// 重载逻辑
}
2.1 重载 +
运算符
代码示例:重载 +
运算符
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 + 运算符Complex operator+(const Complex& other) const {return Complex(real + other.real, imag + other.imag);}void display() const {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(3, 4), c2(1, 2);Complex c3 = c1 + c2; // 使用重载的 + 运算符c3.display(); // 输出 4 + 6ireturn 0;
}
2.2 重载 -
运算符
代码示例:重载 -
运算符
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 - 运算符Complex operator-(const Complex& other) const {return Complex(real - other.real, imag - other.imag);}void display() const {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(5, 7), c2(2, 3);Complex c3 = c1 - c2; // 使用重载的 - 运算符c3.display(); // 输出 3 + 4ireturn 0;
}
2.3 重载 *
运算符
代码示例:重载 *
运算符
#include <iostream>
using namespace std;class Multiply {int value;public://构造函数传参Multiply(int v = 1) : value(v) {}// 重载 * 运算符Multiply operator*(const Multiply& other) const {return Multiply(value * other.value);}void display() const {cout << "Value: " << value << endl;}
};int main() {Multiply m1(5), m2(6);Multiply m3 = m1 * m2; // 使用重载的 * 运算符m3.display(); // 输出 Value: 30return 0;
}
2.4 重载 ==
运算符
代码示例:重载 ==
运算符
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 == 运算符,即判断两个复数是否相等bool operator==(const Complex& other) const {return (real == other.real) && (imag == other.imag);//实部和虚部相同时这两个复数相同}void display() const {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(3, 4), c2(3, 4), c3(1, 2);if (c1 == c2) {//这里因为是两个复数对象在比较是否相等,故在这里会自动调用==重载cout << "c1 and c2 are equal" << endl;} else {cout << "c1 and c2 are not equal" << endl;}if (c1 == c3) {//同上cout << "c1 and c3 are equal" << endl;} else {cout << "c1 and c3 are not equal" << endl;}return 0;
}
4. 流插入运算符 <<
和流提取运算符 >>
的重载
这两个运算符通常需要将 左操作数 定义为 ostream
或 istream
,因此它们必须通过 友元函数 实现。
语法格式:
friend ostream& operator<<(ostream& out, const Type& obj);
friend istream& operator>>(istream& in, Type& obj);
代码实例:重载 <<
和 >>
运算符
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载 << 运算符friend ostream& operator<<(ostream& out, const Complex& c) {out << c.real << " + " << c.imag << "i";//输出一个完整的复数return out;}// 重载 >> 运算符friend istream& operator>>(istream& in, Complex& c) {cout << "输入负数的实数部分和虚数部分: ";in >> c.real >> c.imag;//输入虚数的实部和虚部return in;}
};int main() {Complex c1;cin >> c1; // 输入重载,用于将只能输入实部和虚部的功能转化为能输入一个完整的复数输出cout << "Result: " << c1 << endl; // 输出重载return 0;
}
关于in和out:
1.out和in是什么?
out
和 in
其实是 大类的概念,它们属于 C++ 标准库中定义的 输入输出流体系,包含了很多 具体的输入/输出流对象。
out
:输出流对象(如cout
),用于输出数据到屏幕。in
:输入流对象(如cin
),用于从键盘读取输入数据。
2.out
:输出流对象
这一行代码:
out << c.real << " + " << c.imag << "i";
out
是输出流对象,比如cout(这是一个标准输出流/屏幕输出)
。<<
运算符 将c.real
、" + "
和c.imag
拼接成一串数据,送到输出流out
,然后显示到屏幕上。- 所以,这里是在将
c.real
和c.imag
的值以"real + imagi"
的格式输出到屏幕。
3.in
:输入流对象
这一行代码:
in >> c.real >> c.imag;
in
是输入流对象,比如cin(这是一个标准输入流/键盘输入)
。>>
运算符 从键盘输入流中读取用户输入的数据,然后赋值给c.real
和c.imag
。- 这里的
c.real
和c.imag
属于参数c
对象的成员变量。
5. 类型转换运算符重载
类型转换运算符重载允许自定义类的对象能够隐式或显式地转换为其他指定的类型,比如可以让自定义类对象转换为基本数据类型(如 int
、double
等),或者转换为其他用户自定义类型。这样做的好处是能够使自定义类更好地融入到 C++
语言已有的类型体系中,方便在各种需要相应类型值的场景中使用类对象。
5.1语法格式:
operator 目标类型() const {// 转换的具体实现逻辑,返回目标类型的值return 具体要返回的值;//必须返回转换后的值
}
operator
:表示重载的类型转换运算符。目标类型
:要转换成的目标数据类型(例如int
、float
等)。const
(可选):表示该函数不会修改类的成员变量。- 返回值:必须返回转换后的值。
5.2 特点
- 没有参数:类型转换运算符重载函数不能有参数。
- 不能指定返回类型:返回类型必须是转换目标的类型(即类型名)。
class ErrorExample { public:int operator double() const {// 错误写法,不能写返回类型 intreturn 0;} };
- 可以重载多个不同类型:可以为一个类重载多个类型转换运算符。
- 隐式调用:类型转换运算符重载可以在需要时自动调用。
5.3 应用场景
- 将 类对象 转换为 基本数据类型(如
int
、float
)。 - 将 类对象 转换为 另一个类的对象。
在 C++ 运算符重载 中,强制类型转换运算符重载 是一个比较特殊的知识点。下面我会详细讲解关于强制类型转换的相关知识点,包括定义、语法、特点、应用场景和代码示例。
5.4 代码示例
示例 1:将类对象转换为 int
类型
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 重载类型转换运算符,将 Complex 转换为 intoperator int() const {return real; // 返回实部,作为转换后的值}void display() const {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(3, 4);// 将 c1 转换为 int 类型int intValue = c1;cout << "Complex object: ";c1.display();cout << "Converted to int: " << intValue << endl;return 0;
}
输出结果:
Complex object: 3 + 4i Converted to int: 3
解释
- 通过重载
operator int()
,当我们写int intValue = c1;
时,编译器自动调用重载的类型转换函数。 - 返回值为
c1
的实部real
,因此intValue
变成了3
。
示例 2:将类对象转换为 float
类型
#include <iostream>
using namespace std;class Distance {float meters;public:Distance(float m = 0) : meters(m) {}// 重载类型转换运算符,将 Distance 转换为 floatoperator float() const {return meters; // 返回距离值}void display() const {cout << meters << " meters" << endl;}
};int main() {Distance d(5.75);// 将 d 转换为 float 类型float distanceValue = d;cout << "Distance object: ";d.display();cout << "Converted to float: " << distanceValue << endl;return 0;
}
输出结果
Distance object: 5.75 meters Converted to float: 5.75
解释
- 重载
operator float()
,实现Distance
类到float
类型的转换。 - 当写
float distanceValue = d;
时,编译器自动调用该函数,返回meters
的值。
示例 3:将类对象转换为另一个类对象
#include <iostream>
using namespace std;class Fahrenheit;class Celsius {float temperature;public:Celsius(float temp = 0) : temperature(temp) {}// 类型转换运算符:将 Celsius 转换为 Fahrenheitoperator Fahrenheit();void display() const {cout << "Celsius: " << temperature << "°C" << endl;}
};class Fahrenheit {float temperature;public:Fahrenheit(float temp = 0) : temperature(temp) {}void display() const {cout << "Fahrenheit: " << temperature << "°F" << endl;}friend class Celsius; // 声明 Celsius 为友元类
};// 定义 Celsius 到 Fahrenheit 的类型转换
Celsius::operator Fahrenheit() {return Fahrenheit(temperature * 9 / 5 + 32); // 摄氏度转华氏度
}int main() {Celsius c(25); // 25°CFahrenheit f = c; // 自动调用类型转换运算符c.display();f.display();return 0;
}
输出结果
Celsius: 25°C Fahrenheit: 77°F
解释
Celsius
类重载了类型转换运算符,将Celsius
对象转换为Fahrenheit
对象。- 当写
Fahrenheit f = c;
时,自动调用重载的operator Fahrenheit()
,进行摄氏度到华氏度的转换。
示例4:将自定义类对象转换为另一个自定义类类型(假设存在 Point
和 Vector
类,将 Vector
转换为 Point
)
#include <iostream>
using namespace std;// 点类,二维坐标表示
class Point {
private:int x;int y;public:Point(int a = 0, int b = 0) : x(a), y(b) {}void display() {cout << "(" << x << ", " << y << ")" << endl;}
};// 向量类
class Vector {
private:int dx;int dy;public:Vector(int a = 0, int b = 0) : dx(a), dy(b) {}// 重载类型转换运算符,使 Vector 类能转换为 Point 类operator Point() const {return Point(dx, dy);}
};int main() {Vector vec(3, 4);// 隐式调用类型转换运算符,将 Vector 类对象转换为 Point 类对象Point p = vec; p.display();return 0;
}
- 分别定义了
Point
类用于表示二维平面上的点,有x
和y
坐标成员变量;以及Vector
类表示二维向量,有dx
和dy
成员变量。 - 通过在
Vector
类中重载operator Point()
类型转换运算符,定义了将Vector
类对象转换为Point
类对象的规则,即使用Vector
的dx
和dy
分量来构造一个Point
对象。 - 在
main
函数中,当把Vector
类对象赋值给Point
类对象时,就会自动调用重载的转换运算符完成转换。
示例5:将自定义类对象转换为指针类型(以转换为 char*
类型指针为例,模拟一个简单的字符串类转换)
#include <iostream>
#include <cstring>
using namespace std;// 简单的自定义字符串类
class MyString {
private:char* data;int len;public:MyString(const char* str = "") {len = strlen(str);data = new char[len + 1];strcpy(data, str);}~MyString() {delete[] data;}// 重载类型转换运算符,使其能转换为 char* 类型指针operator char*() const {return data;}
};int main() {MyString myStr("Hello, World!");// 隐式调用类型转换运算符,将 MyString 类对象转换为 char* 类型指针char* ptr = myStr; cout << ptr << endl;return 0;
}
- 定义了
MyString
类,内部通过动态分配内存来存储字符串内容,有成员变量data
(指向存储字符串的字符数组)和len
(记录字符串长度)。 - 通过重载
operator char*()
类型转换运算符,使得MyString
类对象可以转换为char*
类型的指针,返回其内部存储字符串的指针data
。 - 在
main
函数里,将MyString
类对象赋值给char*
类型指针变量时,编译器会自动调用重载的转换运算符来进行转换,之后就能像使用普通char*
类型字符串指针一样操作它(比如输出字符串内容)。
6.扩:左操作数
6.1关于左操作数的通俗解释:左操作数 是指在运算符表达式中,运算符左侧的那个操作数。
举个简单的例子:
a + b;
在这个表达式中,运算符 +
左边的 a
就是 左操作数,右边的 b
就是 右操作数。
对于运算符 +
:
- 左操作数:
a
- 右操作数:
b
6.2 运算符重载中的左操作数
- 类成员函数 重载运算符时,左操作数必须是当前类的对象,因为成员函数是由对象调用的。
- 友元函数 重载运算符时,左操作数可以是任意类型(类对象或其他类型),因为友元函数不属于类,可以自由指定操作数。
6.3 代码实例:成员函数与友元函数的左操作数
6.3.1 类成员函数中的左操作数
在类成员函数中重载运算符时,左操作数是调用运算符的对象(当前对象 this
):
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 成员函数重载 +Complex operator+(const Complex& other) {cout << "Left operand: " << real << " + " << imag << "i" << endl;return Complex(real + other.real, imag + other.imag);}void display() {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(1, 2), c2(3, 4);Complex c3 = c1 + c2; // c1 是左操作数,c2 是右操作数c3.display();return 0;
}
输出:
Left operand: 1 + 2i 4 + 6i
解释:
- 表达式
c1 + c2
中,c1
是 左操作数,会调用成员函数operator+
。 other
参数是 右操作数,即c2
。
6.3.2 友元函数中的左操作数
在友元函数中,左右操作数都作为参数传递,因此 左操作数可以是非类对象:
#include <iostream>
using namespace std;class Complex {int real, imag;public:Complex(int r = 0, int i = 0) : real(r), imag(i) {}// 友元函数重载 +friend Complex operator+(const Complex& c1, const Complex& c2) {cout << "Left operand: " << c1.real << " + " << c1.imag << "i" << endl;return Complex(c1.real + c2.real, c1.imag + c2.imag);}void display() {cout << real << " + " << imag << "i" << endl;}
};int main() {Complex c1(1, 2), c2(3, 4);Complex c3 = c1 + c2; // 左操作数是 c1,右操作数是 c2c3.display();return 0;
}
输出:
Left operand: 1 + 2i 4 + 6i
解释:
- 表达式
c1 + c2
中,c1
是左操作数,c2
是右操作数。 - 在友元函数中,左右操作数通过参数列表传入,不需要依赖
this
指针。
6.4 左操作数与运算符重载的联系
类成员函数:
- 左操作数是调用运算符的对象(通过
this
指针隐式传入)。 - 示例:
c1 + c2
→ 左操作数是c1
,调用c1.operator+()
。
友元函数:
- 左操作数和右操作数都通过参数列表传递。
- 示例:
c1 + c2
→ 左操作数是c1
,友元函数参数为(c1, c2)
。
6.5 为什么左操作数对运算符重载很重要?
- 类成员函数 的运算符重载要求左操作数是当前类的对象。
- 友元函数 则没有这样的限制,提供了更大的灵活性,适用于左操作数不是类对象的情况。
六、运算符重载的总结
运算符类型 | 重载形式 | 使用场景 |
---|---|---|
单目运算符 | 成员函数 | 负号 - , 递增 ++ |
双目运算符 | 成员或友元函数 | 加 + , 比较 == , 赋值 = |
输入输出运算符 | 友元函数 | 流插入 << , 流提取 >> |
类型转换运算符 | 成员函数 | 类对象与内置类型间的转换 |
七、 关键点归纳
- 成员函数 和 友元函数 是运算符重载的两种实现方式。
- 成员函数:左侧操作数必须是当前类对象。
- 友元函数:适用于左右操作数不同的情况。
- 流插入运算符
<<
和流提取运算符>>
必须用友元函数重载。 - 单目和双目运算符 的重载遵循语法规范,不能改变操作数的数量。
- 类型转换运算符 通过
operator type()
重载实现对象与内置类型的转换。