当前位置: 首页 > news >正文

C++类与对象--5 运算符重载

对已有的运算符进行重新定义,赋予不同的功能,以适应不同的数据类型

5.1 加号运算符

  • 实现两个自定义数据类型的加运算

(1)通过成员函数实现“+”重载

class Number
{
public:Number(int a, int b):m_A(a),m_B(b){}Number(){}Number operator+(Number & num)  // 成员函数重载+运算符{Number newNum;newNum.m_A = this->m_A + num.m_A;newNum.m_B = this->m_B + num.m_B;return newNum;}int m_A;int m_B;
};
​
Number num1(10, 15);
Number num2(15, 20);
Number num3 = num1 + num2; // 本质-->Number num3 = num1.operator+(num2);

(2)通过全局函数实现“+”重载

class Number
{
public:Number(int a, int b):m_A(a),m_B(b){}Number(){}
​int m_A;int m_B;
};
​
Number operator+(const Number & num1, const Number & num2)  // 全局函数重载+运算符
{Number newNum;newNum.m_A = num1.m_A + num2.m_A;newNum.m_B = num1.m_B + num2.m_B;return newNum;
}
​
Number num1(10, 15);
Number num2(15, 20);
Number num3 = num1 + num2; // 本质-->Number num3 = operator+(num1, num2);

(3)重载的运算符也可以发生函数重载-->实现不同功能的加法

class Number
{
public:Number(int a, int b):m_A(a),m_B(b){}Number(){}
​int m_A;int m_B;
};
​
Number operator+(const Number & num1, const Number & num2)  // 全局函数重载+运算符
{Number newNum;newNum.m_A = num1.m_A + num2.m_A;newNum.m_B = num1.m_B + num2.m_B;return newNum;
}
​
Number operator+(const Number & num1, int & a)  // +运算符函数重载(形参类型不同)
{Number newNum;newNum.m_A = num1.m_A + a;newNum.m_B = num1.m_B + a;return newNum;
}
​
Number num1(10, 15);
Number num2(15, 20);
Number num3 = num1 + num2; // 本质-->Number num3 = operator+(num1, num2);
int a = 10;
Number num4 = num1 + a; // 本质-->Number num4 = operator+(num1, a);

5.2 左移运算符重载

  • 实现自定义数据类型输出

(1)只能使用全局函数实现“<<”重载

class Number
{
public:int m_A = 10;int m_B = 20;
};
​
std::ostream & operator<<(std::ostream & cout, Number & num)
{cout << num.m_A << num.m_B;return cout;    // 用于链式编程 cout << endl;
}
​
int main()
{Number num;std::cout << num << std::endl;  // 本质operator<<(cout, num)// 重载的<<函数返回了ostream对象,可以链式编程
}

(2)“<<”重载函数访问私有成员-->友元

class Number
{friend std::ostream & operator<<(std::ostream & cout, Number & num); // 重载函数友元
private:int m_A = 10;int m_B = 20;
};
​
std::ostream & operator<<(std::ostream & cout, Number & num)
{cout << num.m_A << num.m_B;return cout;    // 用于链式编程 cout << endl;
}
​
int main()
{Number num;std::cout << num << std::endl;
}

5.3 递增运算符重载

  • 实现自定义数据类型自加

(1)前置++重载

class MyInt
{
public:MyInt(int a):m_a(a){}MyInt & operator++() // 重载前置++,用于对象成员自加{this->m_a = this->m_a + 1;retun *this;}int m_a;
};
​
std::ostream & operator<<(std::ostream & cout, MyInt a) // 重载左移运算符,用于对象输出
{cout << a.m_a;return cout;
}
​
int main()
{MyInt myint(10);std::cout << ++myint << std::endl;
}

(2)后置++重载

class MyInt
{
public:MyInt(int a):m_a(a){}MyInt operator++(int) // 重载后置++,使用int占位参数区分前置++和后置++重载{Myint tempint = *this; // 默认拷贝构造this->m_a = this->m_a + 1;return tempint;}
​int m_a;
};

5.4 赋值运算符重载

  • C++编译器为类提供默认赋值运算符重载函数operator=,对属性进行赋值
  • 自定义赋值运算符重载,实现对自定义类型数据进行赋值
  • 存在堆区成员属性:先清空自身堆区成员,再进行深拷贝
  • 两个已经创建好的对象,使用=,则使用的是重载赋值运算符(与默认拷贝函数的区别)
class Person
{
public:std::string m_name;int * m_age;
​Person(int age, std::string name){m_name = name;m_age = new int(age);}Person & operator=(const Person & p) // 重载赋值运算符{m_name = p.m_name;if(m_age != NULL) // 先删除自身从堆申请的内存{delete m_age;m_age = NULL;}m_age = new int(*p.m_age); // 使用传入的数据重新从堆区申请内存return *this; // 返回当前对象,用于链式编程:a=b=c}~Person(){if(m_age != NULL){delete m_age;m_age = NULL;}}
};
​
void test01()
{Person p1(10, "zhangsan");Person p2(30, "lisi");Person p3(20, "wangwu");p3 = p1 = p2;
}

5.5 关系运算符重载

  • 重载关系运算符,实现自定义数据类型之间的比较

class Person
{
public:int m_age;std::string m_name;Person(int age, std::string name):m_age(age),m_name(name){}bool operator==(const Person & p) // 重载==运算符,判断两个对象是否相等{if((m_age == p.m_age) && (m_name == p.m_name)){return true;}return false;}bool operator!=(const Person & p) // 重载!=运算符,判断两个对象是否不相等{if((m_age == p.m_age) && (m_name == p.m_name)){return false;}return true;}
};

5.6 函数调用运算符重载

  • 重载括号运算符,实现仿函数调用

class MyPrint
{
public:void operator()(int val) // 重载(),实现仿函数{std::cout << val << std::endl;}
};
​
int main()
{MyPrint printFunc;printFunc(10); // 类似函数的调用
}

相关文章:

  • 【Canvas与图标】圆角方块蓝星CSS图标
  • 纯前端实现图文识别 OCR
  • 异步委托执行管理器:更新
  • 嵌入式培训之数据结构学习(六)树(二叉树)、哈希表、内核链表
  • 理解 Swift 逃逸闭包与 implicit `self`
  • virtual下Ubuntu24.04版本上配置网络与外网和宿主机之间互通
  • ros2-类继承,lambda,共享指针,多线程
  • 【C++】C++的IO流
  • 数据结构学习笔记—初识数据结构
  • 【机器学习】线性回归和损失函数
  • 特征值与特征向量的计算——PCA的数学基础
  • Java SpringBoot 集成 SpringSecurity
  • BC27 计算球体的体积
  • VS2017编译openssl3.0.8
  • 【成品设计】STM32和UCOS-II的项目
  • 命令行登录 MySQL 报 Segmentation fault 故障解决
  • 博客系统功能测试
  • 如何轻松删除电脑上的文件(无法恢复文件)
  • 成功案例丨GEZE与Altair合作推动智能建筑系统开发
  • Nginx端口telnet不通排查指南
  • 央媒:安徽凤阳鼓楼坍塌楼宇部分非文物,系违规复建的“假古董”
  • 中方是否支持或参加俄乌谈判?外交部:支持一切有利于和平的努力
  • 春决火爆的背后,PEL如何做大这块电竞蛋糕
  • 一座与人才共成长的理想之城,浙江嘉兴为何如此吸引人?
  • 经济日报评论员:拧紧“带头过紧日子”的制度螺栓
  • 张宇祥已任上海闵行区委常委、副区长