C++作为一门面向对象的编程语言,运算符重载是其面向对象特性的一部分。运算符重载可以让程序员自定义类型的行为,实现语言内建类型同样的语法。
一、运算符重载简介
运算符重载是指在特定情况下对C++中默认的运算符赋予不同的含义,从而能够使用户定义类型表现得像内置类型。运算符重载提高了代码的可读性,使得程序员可以直观地使用操作符来操作某个类型的对象。
预定义的C++运算符可以被重载,包括算术运算符、比较运算符、逻辑运算符、位运算符等。也可以重载输入输出运算符、下标运算符、函数调用运算符等。
二、运算符重载语法
运算符重载是通过一个特殊的成员函数来进行的,该函数名为operator后接需要重载的运算符,如operator+用于重载加号运算符。
class MyClass { public: MyClass operator+(const MyClass& other) const { MyClass result; // 重载加号运算符的代码逻辑 return result; } };
在上述代码中,我们用operator+重载了加号运算符。注意这里我们将该函数定义为类的成员函数,并且该函数返回值是MyClass类的实例。
在使用运算符的时候,可以定义两个对象进行相应的操作,如下:
MyClass a, b; MyClass c = a + b;
在这个例子中,我们给MyClass定义了加号运算符,所以可以像使用内置类型一样使用加号来操作自定义类型。
三、重载运算符的注意事项
1. 运算符重载的参数
运算符重载可以接受0个或多个参数。自增自减运算符通常只接受一个参数。对于算术运算符和一些其他运算符,通常使用左侧的操作数作为参数。如果想要支持a/b,也要支持b/a,所以为了支持双向性,通常把操作数的顺序当成副作用最小的顺序进行定义(若操作数类型不同,则要考虑强制类型转换的开销)。
2. 运算符重载的返回值类型
对于大多数算数运算符,比如+和-,返回值类型应该是值得类型,这也是标准库里各种迭代器的写法。但有时候,比如+=运算符不需要返回值,或者会修改第一个操作数并返回一个引用就可以实现优化。
3. 运算符重载的约定
不应该改变原始对象,运算符函数并不一定改变它所操作的对象。如果想要改变对象,应使用+=等运算符来实现。
4. 运算符重载的常量成员函数
对于只读操作数(比如+i),运算符函数要声明为常量成员函数以表示它们不会改变该对象。否则,该函数将无法使用const对象。
5. 运算符重载的局限性
运算符不适用于所有情况,尤其是对于那些不接受实际类型的二元运算符,比如:: 运算符。
以下是一个完整的示例代码,演示了如何重载加号运算符:
#include <iostream> class Complex { public: Complex(double r, double i) : real(r), imag(i) {} // 重载加号运算符 Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } // 重载输出运算符 friend std::ostream& operator<<(std::ostream& os, const Complex& cmp); private: double real; double imag; }; std::ostream& operator<<(std::ostream& os, const Complex& cmp) { os << cmp.real << " + " << cmp.imag << "i"; return os; } int main() { Complex c1(3, 4), c2(2, 5); Complex c3 = c1 + c2; std::cout << c3 << std::endl; return 0; }
运行结果:
5 + 9i
四、总结
运算符重载是C++中的一项强大的特性,使得程序员可以像使用内置类型一样使用自定义类型。需要注意的是,不应该改变原始对象,在重载运算符时需要遵循一定的约定。