C++(4) 运算符重载

2023-05-16

C++学习心得(1)运算符重载
——from 谭浩强.C++面向对象程序设计(第一版)

2014/10/6

4.1什么是运算符重载

    用户根据C++提供的运算符进行重载,赋予它们新的含义,使之一名多用。

 

4.2运算符重载的方法

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。运算符重载实质上是函数的重载

 

声明重载运算符+的函数:

Complex operator + (Complex &c2);

定义重载运算符+的函数:

函数返回值类型 operator 运算符名称 (形参列表)
{
        对运算符的重载处理;
}


可以说:函数operator+重载了运算符 +

 

4.3 重载运算符的规则

        <1>只能重载已有的C++运算符;

        <2>不允许重载的运算符(5个):

                .(成员访问运算符)

                .*(成员指针访问运算符)

                ::  (域运算符)

                sizeof(长度运算符)

                ?: (条件运算符)

        <3>不能改变操作数的个数;

        <4>不能改变优先级;

        <5>不能改变结合性

        <6>重载运算符的函数不能有默认参数;

        <7>重载运算符的函数参数不能全部是C++标准类型,(至少有一个是类对象或类对象的引用)防止用户修改用于标准类型数据的运算符的性质。

        <8>”=”和”&”不必用户重载;

        <9>重载运算符功能应类似于其用于标准类型时所实现的功能;

        <10>运算符重载函数可以是类的成员函数类的友元函数普通函数

 

4.4 运算符重载函数作为类成员函数和友元函数

#include <iostream>
using namespace std;
 
class Complex
{
    public:
       Complex()  {   real= 0; imag = 0;  }
       Complex(doubler, double i) {   real = r; imag = i;  }
       friendComplex operator + (Complex &c1, Complex &c2);
       voiddisplay();
    private:
       doublereal;
       doubleimag;
};
 
Complex operator + (Complex &c1,Complex &c2)
{
    returnComplex(c1.real+c2.real, c1.imag+c2.imag);
}
 
void Complex::display()
{
    cout<< "(" << real << "," << imag<< "i)" << endl;
}
 
int main()
{
    Complexc1(3, 4), c2(5, -10), c3;
    c3= c1 + c2;
    cout<< "c1 = "; c1.display();
    cout<< "c2 = "; c2.display();
    cout<< "c1 + c2 = "; c3.display();
 
    return0;
}


 

在将运算符”+”重载为友元函数后,编译系统将c1+c2解释为

        

operator + (c1, c2)

        如果将运算符重载函数作为成员函数,必须要求运算表达式第一个参数(即运算符左侧的操作数)是一个类对象,而且与运算符函数的类型相同。

        将双目运算符重载为友元函数时,不要求第一个参数必须为类对象,但使用运算符的表达式中,要求运算符左侧的操作数与第一个参数对应,运算符右侧的操作数与函数的第二个参数对应。数学上的交换律在此不适用。


        一般将单目运算符重载为成员函数,将双目运算符重载为友元函数。

 

4.5 重载双目运算符

    没什么好谈的,简单的看一下字符串的初始化。

声明构造函数:

    String(char *);

定义构造函数: 

String::String(char* str)
{
       p = str;
}


初始化:

 String string1(“Hello”);


4.6 重载单目运算符

#include <iostream>
using namespace std;
 
class Time
{
    public:
       Time(){   minute = 0; sec = 0; }
       Time(intm, int s):minute(m), sec(s) {}
       Timeoperator ++ ();                      //  声明前置自置运算符
       Timeoperator ++(int);                        //  声明后置自增运算符
       voiddisplay()
       {
           cout<< minute << ":" << sec << endl;
       }
    private:
       intminute;
       intsec;
};
 
Time Time::operator ++ ()
{
    if(++sec>= 0)
    {
       sec-= 60;
       ++minute;
    }
 
    return*this;                                 //  返回的是自加后的当前对象
}
Time Time::operator ++ (int)
{
    Timetemp(*this);
    sec++;
    if(sec>= 60)
    {
       sec-= 60;
       ++minute;
    }
 
    returntemp;                                  //  返回的是自加前的对象
}
 
int main()
{
    Timetime1(34, 59), time2;
 
    cout<< "time1:";
    time1.display();
   
    ++time1;
    cout<< "++time1:";
    time1.display();
 
    time2= time1++;
    cout<< "time1++";
    time1.display();
 
    cout<< "time2:";
    time2.display();
 
    return0;
}


        C++约定:如果在自增/自减运算符重载函数中,增加一个int型形参,就是自增/自减运算符函数。

Time operator ++ ();
Time operator ++ () (int);

   

        不论是前置自增运算符还是后置自增运算符作用于变量或者对象都会有自增的效果。两个函数返回的结果是不同的,前置的返回的是修改后的对象本身,后置的返回的是自加前的对象

 

4.7 重载流插入运算符和流提取运算符

        输入流类istream

        输出流类ostream

        函数形式如下:   

friendistream & operator >> (istream &, 自定义类 &);
friendostream & operator << (ostream &, 自定义类 &);

        函数的返回值类型和第一个参数都必须是 istream &类型,第二个参数是要进行输入的操作的类。

        只能将重载”>>”和”<<”的函数作为友元函数或普通函数,而不能将它们定义为成员函数。

声明:

friend ostream& operator << (ostream &, Complex &);


定义:

ostream & operator << (ostream & output, Complex &c)
{
    output << "(" <<c.real << "+" << c.imag << "i)" <<endl;
    return output;
}

函数中的形参output是ostream类对象的引用,形参名output是用户任意起的。编译器将cout << c3解释为

operator<<(cout, c3)调用函数。return output的作用是连续向输出流插入信息。将输出流cout的现状返回,即保留输出流现状。

 

4.8    不同类型数据间的转换

        隐式类型转换

        显示类型转换C++:int(89.5)而语言是C(int)89.5

4.8.2  利用转换构造函数进行类型转换

        转换构造函数的作用是将一个其他类型的数据转换成一个指定的类的对象

几种构造函数:

        (1)默认构造函数;     Complex();

        (2)初始化构造函数;    Complex(double r, doublei);

        (3)复制构造函数;     Complex(Complex &c);

        (4) 转换构造函数;    Complex(double r) {  real = r; imag = 0;  };

几处运用:(无名对象)

(1)c1 = Complex(3.6);
(2)c = c1 + Complex(3.6);
        通常把有一个参数的构造函数用作类型转换,所以称为转换构造函数,但有一个参数的构造函数也可以不用作类型转换。不仅可以将一个标准数据类型转换成类对象,也可以将另一个类的对象转换成构造函数所在的类对象。一定要注意对象中的数据必须是公用成员才可以被类外引用。

4.8.3  用类型转换函数进行类型转换

类型转换函数的作用是将一个类的对象转换成另一个类型的数据。

类型转换函数的形式:

operator类型名 () 		
{                          					
    实现转换的语句;            
}      

                    

        函数没有参数,因为不需要。也没有函数返回值类型,因为其返回值类型是由函数名中指定的类型名确定的。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。

#include<iostream>
using namespace std;
 
class Complex
{
    public:
       Complex(){   real = 0; imag = 0;  }                        //默认构造函数
       Complex(doubler) {  real = r; imag = 0;}               // 转换构造函数
       Complex(doubler, double i) {   real = r; imag = i;  }      //初始化的构造函数
       friendComplex operator + (Complex c1, Complex c2);         //重载运算符“+”的友元函数
       voiddisplay();
    private:
       doublereal;
       doubleimag;
};
 
Complex operator + (Complex c1, Complex c2)
{
    returnComplex(c1.real+c2.real, c1.imag+c2.imag);
}
 
void Complex::display()
{
    cout<< "(" << real << "," << imag<< "i)" << endl;
}
 
int main()
{
    Complexc1(3, 4), c2(5, -10), c3;
    c3= c1 + 2.5;
    c3.display();
 
    return0;
}

        转换构造函数和类型转换运算符有一个共同的功能:当需要的时候编译器会自动地调用这些函数,建立一个无名的临时对象,即隐式调用。

总结:将单目运算符重载为成员函数,将双目运算符重载为友元函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++(4) 运算符重载 的相关文章

随机推荐

  • flashcache原理

    介绍flashcache的文章很多 xff0c 我就不废话了 使用上 xff0c 有余峰老哥的 文章 xff1b 原理上 xff0c 有ningoo同学的 flashcache系列 但是ningoo同学漏掉了device mapper和fl
  • 无人机算法之PID

    xff08 未完成 xff09 一 PID介绍 xff08 百度百科 xff09 PID 控制器 xff08 比例 积分 微分控制器 xff09 是一个在工业控制应用中常见的反馈回路部件 xff0c 由比例单元 P 积分单元 I 和微分单元
  • java:接口、lambda表达式与内部类

    接口 xff08 interface 接口用来描述类应该做什么 xff0c 而不指定他们具体应该如何做 接口不是类 xff0c 而是对符合这个接口的类的一组需求 接口定义的关键词是interface span class token key
  • 卫星系统算法课程设计 - 第二部分 qt的安装与创建项目

    上一篇文章只讲了基本的东西 xff0c 这一篇要完成qt的安装 xff0c 构建项目 xff0c 并且将上一篇的代码导入进去 某比利比例搜qt安装 xff0c 看到qt5 14 2的下载安装 xff0c 跟着做 1 创建项目 创建新项目 x
  • 无人机-材料准备

    xff08 未完成 xff09 一 使用空心杯电机 xff0c 型号8520 xff0c 1S版本 xff0c 约5G每只 二 空心杯机架 xff0c 型号QX90 xff0c 约8 5g 三 使用55MM桨 四 1S 600MA电池 五
  • CMake中链接库的顺序问题

    原文链接 xff1a https blog csdn net lifemap article details 7586363 cmake中链接库的顺序是a依赖b xff0c 那么b放在a的后面 例如进程test依赖a库 b库 a库又依赖b
  • 鸿蒙wifi Demo运行

    title 鸿蒙Wi Fi Demo运行 date 2021 1 1 22 25 10 categories harmony 本文首发于LHM s notes 欢迎关注我的博客 坑有点多 由于之前没有看过wifi的内核态代码 xff0c 所
  • 将TensorFlow训练好的模型迁移到Android APP上(TensorFlowLite)

    将TensorFlow训练好的模型迁移到Android APP上 xff08 TensorFlowLite xff09 1 写在前面 最近在做一个数字手势识别的APP xff08 关于这个项目 xff0c 我会再写一篇博客仔细介绍 xff0
  • 汉诺塔代码图文详解(递归入门)

    游戏规则 xff1a 已知条件存在A B C三根柱子 xff0c A上套有N片圆盘 如下图 目的将A上的所有圆盘移到C上约束条件每次只能移动一片圆盘 xff0c 且整个过程中只能出现小圆盘在大圆盘之上的情况 首先我们模拟 N 61 2 xf
  • STM32 最小系统电路简析

    文章目录 一 最小系统的组成1 供电电路2 外部晶振3 BOOT选择4 复位电路 二 最小系统实例1 STM32F103C8T6最小系统 三 各部分组成简析1 供电电路设计2 外部晶振原理3 BOOT设计4 复位电路设计 一 最小系统的组成
  • 带参数的宏的问题

    include 34 iostream 34 using namespace std define COMPUTE XX a a a 43 a 2 int main int a 61 2 int test1 61 COMPUTE XX 43
  • python_imbalanced-learn非平衡学习包_02_Over-sampling过采样

    python imbalanced learn非平衡学习包 01 简介 python imbalanced learn非平衡学习包 02 Over sampling过采样 后续章节待定 希望各位认可前面已更 您的认可是我的动力 Over s
  • TX2+JetPack3.2.1+opencv3.3.1+caffe+realsense2.0环境配置教程

    TX2 开箱 一共6样 xff0c 开机之后自带ubuntu16 04LTS的系统 xff0c ARMv8的处理器 xff0c 所以有些指令 xff0c 安装包必须与arm结构保持一致 开机之后 xff0c 按照指示进入图形界面 xff1a
  • 初视openwrt

    openwrt是一个微型的嵌入式操作系统 在编译的时候需要安装许多的工具和库 预置环境 xff1a sudo apt get install g 43 43 libncurses5 dev zlib1g dev bison flex unz
  • 滑动窗口详解

    前言 滑动窗口是双指针的一种特例 xff0c 可以称为左右指针 xff0c 在任意时刻 xff0c 只有一个指针运动 xff0c 而另一个保持静止 滑动窗口路一般用于解决特定的序列中符合条件的连续的子序列的问题 滑动窗口的时间复杂度是线性的
  • RT-Thread入门教程,环境配置和第一个代码

    1 前言 RT Thread这一个操作系统获得很多工程师的好评 xff0c 使用简单 xff0c 支持多 xff0c 有软件包可以下载 xff0c 甚至未来会有更多MicroPython的支持 xff0c 能够兼容主流的一些MCU xff0
  • DHT12温湿度传感器IIC,I2C接口调试心得和代码说明

    来源 xff1a http www fuhome net bbs forum php mod 61 viewthread amp tid 61 2141 DHT11那个单总线的温湿度传感器用的很多了 xff0c aosong推出了DHT12
  • 升级windows11如何在电脑上启用TPM2.0

    本文适用于无法升级到 Windows 11 xff0c 因为他们的电脑当前未启用 TPM 2 0 或其电脑能够运行 TPM 2 0 xff0c 但并未设置为运行 TPM 2 0 1 下载微软电脑健康状况检查 下载地址为 xff1a Wind
  • python调用谷歌翻译

    from GoogleFreeTrans import Translator if name 61 61 39 main 39 translator 61 Translator translator src 61 39 en 39 dest
  • C++(4) 运算符重载

    C 43 43 学习心得 xff08 1 xff09 运算符重载 from 谭浩强 C 43 43 面向对象程序设计 第一版 2014 10 6 4 1什么是运算符重载 用户根据C 43 43 提供的运算符进行重载 xff0c 赋予它们新的