2025年4月8日 星期二 乙巳(蛇)年 正月初九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++运算符重载

时间:02-10来源:作者:点击数:75

+运算符重载

  • #include <iostream>
  • using namespace std;
  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • };
  • Number operator+(const Number &n1, const Number &n2) {
  • Number result(0);
  • result.value = n1.value + n2.value;
  • return result;
  • }
  • Number operator+(const Number &n1, int n2) {
  • Number result(0);
  • result.value = n1.value + n2;
  • return result;
  • }
  • int main() {
  • Number num1 = Number(10) + Number(20);
  • Number num2 = Number(10) + 5;
  • cout << "num1 = " << num1.value << endl;
  • cout << "num2 = " << num2.value << endl;
  • return 0;
  • }

函数中的参数顺序和调用顺序必须一致,如下面的调用就报错了:

在这里插入图片描述

我们定义Numberint相加的函数时,Number参数是在前面的,则在使用时也必须保持Number在前面。

定义的顺序也可以修改,必须让int在前面,则调用的时候int就要写在前面如下:

在这里插入图片描述

<<运算符重载

与加号运算符一样,可以声明为类的成员函数,也可以声明为全局函数,这里就只写一种,示例如下:

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • };
  • Number& operator<<(Number & n1, Number & n2) {
  • n1.value = n1.value + n2.value;
  • return n1;
  • }
  • int main() {
  • Number n1 = Number(1);
  • Number n2 = Number(2);
  • Number n3 = Number(3);
  • Number result = n1 << n2 << n3;
  • cout << result.value << endl;
  • return 0;
  • }

注:左移运算符的返回值必须是引用类型才能连续调用左移符号,否则只能调用一次,如下:

  • Number operator<<(Number & n1, Number & n2) {
  • n1.value = n1.value + n2.value;
  • return n1;
  • }
  • int main() {
  • Number n1 = Number(1);
  • Number n2 = Number(2);
  • Number result = n1 << n2;
  • cout << result.value << endl;
  • return 0;
  • }

如上代码,<<函数的返回值不是引用类型的,则<<不能连续使用,如下是错误的:

在这里插入图片描述

另外需要注意,对象不能使用匿名对象,匿名对象无法使用<<来操作,如下是错误的:

在这里插入图片描述

另外,<<函数也是可以重载的,如下:

  • Number & operator<<(Number & n1, Number & n2) {
  • n1.value = n1.value + n2.value;
  • return n1;
  • }
  • Number & operator<<(Number & n1, int n2) {
  • n1.value = n1.value + n2;
  • return n1;
  • }
  • int main() {
  • Number n1 = Number(1);
  • Number n2 = Number(2);
  • Number n3 = Number(3);
  • Number result = n1 << n2 << n3 << 4 << 5;
  • cout << result.value << endl;
  • return 0;
  • }

另外,如果访问了类的私有成员,也可以设置为友元,如下:

  • class Number {
  • friend Number & operator<<(Number & n1, Number & n2);
  • friend Number & operator<<(Number & n1, int n2);
  • friend int main();
  • private:
  • int value;
  • public:
  • explicit Number(int n) : value(n) { }
  • };
  • Number & operator<<(Number & n1, Number & n2) {
  • n1.value = n1.value + n2.value;
  • return n1;
  • }
  • Number & operator<<(Number & n1, int n2) {
  • n1.value = n1.value + n2;
  • return n1;
  • }
  • int main() {
  • Number n1 = Number(1);
  • Number n2 = Number(2);
  • Number n3 = Number(3);
  • Number result = n1 << n2 << n3 << 4 << 5;
  • cout << result.value << endl;
  • return 0;
  • }

通过<<实现打印对象,如下:

在这里插入图片描述

如上代码,cout不知道如何打印Number对象,所以IDE直接就报错了,说白了就是系统库并没有提供接收Number参数的<<函数,所以我们自己可以提供一个,如下:

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • };
  • ostream & operator<<(ostream & out, const Number & number) {
  • printf("number.value = %d ", number.value);
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(3);
  • cout << n1 << n2 << "hello" << endl;
  • return 0;
  • }

运行结果如下:

  • number.value = 1 number.value = 3 hello

++运算符重载

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • // 前++
  • Number & operator++() {
  • value++;
  • return *this;
  • }
  • // 后++
  • Number operator++(int) {
  • Number copy = *this; // 利用拷贝构造函数创建出一个复本
  • value++;
  • return copy;
  • }
  • };
  • ostream & operator<<(ostream & out, const Number & number) {
  • out << number.value;
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(1);
  • cout << ++n1 << endl;
  • cout << n2++ << endl; // 这里打印的并不是n2,而是++操作返回的一个副本对象
  • cout << n2 << endl;
  • return 0;
  • }

赋值运算符重载

c++编译器至少给一个类添加4个函数:

  • 默认构造函数(无参,函数体为空)
  • 默认析构函数(无参,函数体为空)
  • 默认拷贝构造函数,对属性进行值拷贝
  • 赋值运算符 operator=, 对属性进行值拷贝(会有浅拷贝的问题)

示例如下:

  • class Number;
  • ostream & operator<<(ostream & out, const Number & number);
  • class Number {
  • public:
  • int * valuePointer;
  • explicit Number(int n) {
  • valuePointer = new int(n);
  • }
  • ~Number() {
  • delete valuePointer;
  • }
  • Number & operator=(const Number& number) {
  • // 预防浅拷贝问题,编译器默认是浅拷贝,如:valuePointer = number.valuePointer
  • cout << "自身value = " << *valuePointer << ", 传入value = " << *number.valuePointer << endl;
  • *valuePointer = *number.valuePointer;
  • return *this;
  • }
  • };
  • ostream & operator<<(ostream & out, const Number & number) {
  • out << *number.valuePointer;
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(2);
  • Number n3(3);
  • n1 = n2 = n3;
  • cout << n1 << endl;
  • cout << n2 << endl;
  • cout << n3 << endl;
  • return 0;
  • }

运行结果如下:

  • 自身value = 2, 传入value = 3
  • 自身value = 1, 传入value = 3
  • 3
  • 3
  • 3

这说明赋值操作的优先级是从右到左的。

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • };
  • bool operator==(Number & n1, Number & n2) {
  • return n1.value == n2.value;
  • }
  • ostream & operator<<(ostream & out, const Number & number) {
  • out << number.value;
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(2);
  • Number n3(2);
  • bool result1 = n1 == n2;
  • bool result2 = n2 == n3;
  • cout << result1 << endl;
  • cout << result2 << endl;
  • return 0;
  • }

还有其它的关系,比如:<>!=>=<=等,这些的实现也是一样的,就不写了。

函数调用运行符重载

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • void operator()() {
  • cout << "函数调用: " << value << endl;
  • }
  • };
  • ostream & operator<<(ostream & out, const Number & number) {
  • out << number.value;
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(2);
  • Number n3(3);
  • n1();
  • n2();
  • n3();
  • return 0;
  • }

这个函数调用很奇怪,不知道为什么要搞这种形式。还可加入参数,示例如下:

  • class Number {
  • public:
  • int value;
  • explicit Number(int n) : value(n) { }
  • void operator()() {
  • cout << "函数调用: " << value << endl;
  • }
  • void operator()(int a, string b) {
  • cout << "函数调用: " << value + a << b << endl;
  • }
  • };
  • ostream & operator<<(ostream & out, const Number & number) {
  • out << number.value;
  • return out;
  • }
  • int main() {
  • Number n1(1);
  • Number n2(2);
  • Number n3(3);
  • n1(1, "一");
  • n2(2, "二");
  • n3(3, "三");
  • return 0;
  • }
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门