博客
关于我
C++ primer学习笔记 第十四章 重载运算与类型转换
阅读量:677 次
发布时间:2019-03-16

本文共 2809 字,大约阅读时间需要 9 分钟。

重载运算符在C++中的基础概念

重载运算符是C++中一个强大特性,它允许我们自定义类的运算行为。通过重载运算符,我们可以为用户定义的类增加和内置类型相同的操作符功能,从而使其更加灵活和可扩展。

运算符的定义和使用

重载运算符的定义方式有以下两种:

  • 通过 operator 关键字定义

    例如,定义一个加法运算符可以这样写:

    int operator+(const MyObject& a, const MyObject& b) {    return a + b;}
  • 直接定义

    有时候,如果运算符已经是成员函数,且参数较少,可以直接用 + 的符号来定义运算符。
    例如:

    MyObject operator+(const MyObject& a) {    return new MyObject(a.getValue());}

调用重载运算符的方式与普通运算符相同,但要明确表达我们是调用用户定义的重载版本:

例如:

int data1 = 5;  int data2 = 7;  int sum = data1 + data2; // 调用默认的整数加法运算符  int sum = operator+(data1, data2); // �amakely 调用自定义重载的加法运算符

是否是成员函数

判断一个运算符是否是成员函数,可以通过以下规则:

  • 赋值运算符 (=)下标运算符 [...]函数调用运算符 ()成员访问运算符 (->) 必须是成员函数。
  • 类似 = 的复合赋值运算符(例如 +=, -= 等)通常也应该定义为成员函数。
  • 一些具有对称性的运算符(如算术运算和比较运算符)通常是非成员函数,例如:
    bool operator==(const MyObject& a, const MyObject& b);

    这种运算符不需要是成员函数。

因此,在定义运算符时,要根据具体需求决定是否将其定义为成员函数。

常用运算符可以被重载的示例

可选运算符 不能重载的运算符
+, -, *, /, %, ^ ::, .*, ., ? :
&, ,, ~, !, =, ,= ,, ~, !, -
<, >, <=, >=, ++, --
<<, >>, ==, !=, &&, ||
+=, -=',/=,%=,^=,&=,*=`
[] (下标运算符)
-> (成员访问运算符), -, new, delete
括号 (), 和逗号 ,

注意:某些特殊运算符不允许重载,例如 ::(标量的成员访问)、.*(指向成员的指针下标)、? :(选择表达式中的 :)。

输入和输出运算符的特殊性

输入和输出运算符有一些特别的规则:

  • 输出运算符 (<<)

    输出运算符通常是非成员函数,定义方式通常是:

    std::ostream& operator<<(const MyObject& obj) {    obj.print();    return std::cout;}
  • 输入运算符 (>>)

    输入运算符则要求更加谨慎,因为它们需要处理可能的失败情况。
    例如:

    MyObject operator>>(std::istream& is, MyObject& obj) {    is >> obj.value;    return obj;}

输入运算符的第一个参数通常是输入流的引用,第二个参数是目标对象的非常量引用。

算术和关系运算符

在定义算术和关系运算符时,需要注意以下几点:

  • 传递性和结合律:确保运算符的传递性和与内置运算符相同的结合律。
  • 复合赋值运算符的优先选择:如果类同时需要定义算术运算符和复合赋值运算符(如 +=),通常应优先使用复合赋值运算符,因为它比直接赋值更灵活。

相等运算符的重要性

如果类包含相等性(==),则通常也需要定义不等式运算符(!=),反之亦然。确保相等运算符具有传递性,避免循环依赖。

递增和递减运算符

递增和递减运算符通常是成员函数,定义方式如下:

  • 前置递增运算符:

    MyObject& operator++() {    this->counter++;    return *this;}
  • 后置递增运算符:

    由于与内置运算符保持一致,后置运算符需要接受一个额外的 int 形参(通常不使用):

    MyObject operator++(int) {    // 这里通常无需改变逻辑,建议保持可选性。    return *this;}

同样,递减运算符 (--) 的定义方式与递增类似。

成员访问运算符

成员访问运算符通常被定义为成员函数。例如:

  • 解引用运算符 ->

    MyObject* operator->() {    return *this;}
  • 箭头运算符 -&> 常用于subtotal 类:

    MyObject operator->(const MyObject& rhs) {    return *this / rhs;}

解引用和乘法运算符的区别在于,解引用是一个一元运算符,而乘法是一个二元运算符。

函数调用运算符

函数调用运算符可以像普通函数一样调用,具有类功能:

  • 定义函数调用运算符的方式:

    void operator()() {    doSomething();}
  • 好处是可以将对象当作函数处理。

如果类同时定义多个版本的调用运算符,其参数类型或数量应有所不同,以避免歧义。

标准库的函数对象

C++ 提供了一些标准库定义的函数对象,这些可以用来简化算法编写。例如:

  • 算术函数对象

    std::plus
    plus;int result = std::accumulate(std::begin(list), std::end(list), 0, plus);
  • 关系函数对象

    std::greater
    greater;if (std::every_of(greater, begin(list), end(list))) { // 做一些判断}

这些函数对象可以用来处理自定义类中的算术和关系运算。

类型转换运算符

类型转换运算符是成员函数,其名称为 operator type()。它们用于将类的对象转换为目标类型,通常取名为 toType 或者 `type().

性能和错误处理

在实现运算符时,需要注意性能和错误处理:

  • 避免在重载运算符中使用 this,除非必要。
  • 处理可能的运算失败,如输入运算符中缺少数据等。

通过遵循这些规则,我们可以创建一个更加灵活和可靠的类框架。

总结

重载运算符是C++强大功能的体现,它允许我们为类定义一系列自定义的运算符行为。通过理解和遵循上述规则,我们可以更好地利用重载运算符,避免潜在的问题,从而提高代码质量和可维护性。

转载地址:http://yptqz.baihongyu.com/

你可能感兴趣的文章
nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
nginx配置全解
查看>>
Nginx配置参数中文说明
查看>>
nginx配置域名和ip同时访问、开放多端口
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置如何一键生成
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>