C++运算符重载的方法详细解析

运算符重载实质上是函数的重载

重载运算符的函数一般格式如下:

函数类型    operator  运算符名称    (形参表列)

{对运算符的重载处理}

例如,想将“+”用于Complex(复数)的加法运算,函数的原型可以是这样的:


代码如下:

Complex operator + (Complex & c1,Complex &c2);

其中,operator是关键字,时候专门用于定义重载运算符的函数的,运算符名称就是C++提供给用户的预定运算符。

注意:函数名是由operator和运算符组成。

上面的operator+就是函数名,意思是“对运算符+重载“。只要掌握这点,这可以发现,这类函数和其他函数在形式上没有什么区别。

两个形参是Complex类对象的引用,要求实参为Complex类对象。

在定义了重载运算符后,可以说:函数operator+重载了运算符+。

在执行复数相加的表达式c1+c2时(假设c1+c2都已被定义为Complex),系统就会调用operator+函数,把c1+c2作为实参,与形参进行虚实结合。

为了说明把运算符重载后,执行表达式就是调用函数的过程,可以把两个整数相加也想象称为调用下面的函数:


代码如下:

int operator + (int a,int b)
{
          return (a+b);
}

如果有表达式5+8,就调用此函数,将5和8作为调用函数时的形参,函数的返回值为13,这就是通过函数的方法理解运算符。

=====================示例代码1.1==================================


代码如下:

#include<iostream>
using namespace std;
class Complex
{
 public:
  Complex()
  {
   real=0;
   imag=0;
  }
  Complex(double r,double i)
  {
   real=r;
   imag=i;
  }
  Complex operator + (Complex &c2);//声明运算符的"+"函数
  void display();
 private:
  double real;
  double imag;
};
Complex Complex::operator+(Complex &c2)
{
 Complex c;
 c.real=real+c2.real;
 c.imag=imag+c2.imag;
 return c;
}
void Complex::display()
{
 cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
int main()
{
 Complex c1(3,4),c2(5,-10),c3;
 c3=c1+c2;
 cout<<"c1=";
 c1.display();
 cout<<"c2=";
 c2.display();
 cout<<"c3=";
 c3.display();
  return 0;
}

分析:

在main函数中,“c3=c1+c2;”在将运算符+重载为类的成员函数后,C++编译系统将程序中的表达式c1+c2解释为:

c1.operator+(c2);//其中c1+c2是Complex类的对象

即以c2为实参调用c1的运算符重载函数operator+(Complex & c2),进行求值,得到两个复数之和。上面的“operator+”是一个函数名,它是类Complex的成员函数。

在实际工作中,类的声明和类的使用往往是分离的。假如在声明Complex类时,对运算符+,-,*,/都进行了重载,那么使用这个类的用户在编程时可以完全不考虑函数是怎么实现的,

放心大胆地直接使用+,-,*,/进行复数的运算即可,显然十分方便。

对上面的运算符重载函数operator +还可以改写的更简练一些:


代码如下:

Complex Complex::operator+(Complex &c2)
{
 return Complex(c2.real+real,c2.imag+imag);
}

return语句中的Complex(c2.real+real,c2.imag+imag)是建立一个临时对象,它没有对象名,是一个无名对象。

在建立临时对象过程中,调用构造函数。return语句将此临时对象作为函数返回值。

那么,我们将+运算符进行了重载以后,可否将一个常量和一个复数相加呢?比如:


代码如下:

c3=3+c2;        //错误,与形参类型不匹配

这是行不通的,因为我们定义operator +函数的时候,形参是两个Complex的对象,也就是说,实参和形参匹配才可以调用函数。

应写成对象形式,如:


代码如下:

c3=Complex(3,0)+c2;     //正确,类型均为对象

还需要说明的是:运算符被重载后,其原有的功能仍然保留,没有丧失或改变。

例如,运算符+被重载以后,仍然可以用于int,float,double,char类型数据的运算,同时又增加了用于复数相加的功能。

编译系统根据表达式的上下文,即根据运算符两侧(如果是单目运算符则为一侧)的数据类型决定的。

如,对于3+5,则执行整数加法;对于3.4+5.45,则执行双精度数加法;对于两个复数类相加,则执行复数加法。

(0)

相关推荐

  • 浅析C/C++中sort函数的用法

    sort是STL中提供的算法,头文件为#include<algorithm>以及using namespace std; 函数原型如下: template <class RandomAccessIterator> void sort ( RandomAccessIterator first, RandomAccessIterator last ); template <class RandomAccessIterator, class Compare> void sor

  • 深入C++ string.find()函数的用法总结

    #include <string>#include <iostream>using namespace std; void main(){ 复制代码 代码如下: ////find函数返回类型 size_typestring s("1a2b3c4d5e6f7g8h9i1a2b3c4d5e6f7g8ha9i");string flag;string::size_type position;//find 函数 返回jk 在s 中的下标位置 position = s.f

  • C++类静态成员与类静态成员函数详解

    当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享.各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关.静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关. 静态数据成员的用途之一是统计有多少个对象实际存在. 静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的.也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一

  • C++中的friend友元函数详细解析

    友元函数是可以直接访问类的私有成员的非成员函数.它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend. 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性.另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运

  • C++中的哈希容器unordered_map使用示例

    随着C++0x标准的确立,C++的标准库中也终于有了hash table这个东西. 很久以来,STL中都只提供<map>作为存放对应关系的容器,内部通常用红黑树实现,据说原因是二叉平衡树(如红黑树)的各种操作,插入.删除.查找等,都是稳定的时间复杂度,即O(log n):但是对于hash表来说,由于无法避免re-hash所带来的性能问题,即使大多数情况下hash表的性能非常好,但是re-hash所带来的不稳定性在当时是不能容忍的. 不过由于hash表的性能优势,它的使用面还是很广的,于是第三方

  • C++ 二维数组参数传递的实现方法

    C++ 二维数组参数传递的实现方法 int a[2][2]={ {4, 6}, {9, 11} }; 我定义了这样一个数组,我想把这个数组作为参数,传递到一个函数中,并要在函数中能引用该二维数组的元素,我该怎么做? 第一种方式是直接传递二维数组,但是必须标明第二维的值,因为如果只是传递a[][],编译器无法分配这样的数组,所以要这样传int a[][3] 第二种方法是传递指针数组方式,即int (*a)[3] 第三种是传递指针方法. 具体实施见代码: 方法1:传递数组,注意第二维必须标明 //二

  • C++运算符重载的方法详细解析

    运算符重载实质上是函数的重载 重载运算符的函数一般格式如下: 函数类型    operator  运算符名称    (形参表列) {对运算符的重载处理} 例如,想将"+"用于Complex(复数)的加法运算,函数的原型可以是这样的: 复制代码 代码如下: Complex operator + (Complex & c1,Complex &c2); 其中,operator是关键字,时候专门用于定义重载运算符的函数的,运算符名称就是C++提供给用户的预定运算符. 注意:函数

  • python 特殊属性及方法详细解析

    目录 概述 特殊属性 1. _ _ name _ _ 2._ _ bases _ _ 和_ _ base _ _ 以及 _ _ mro _ _ 3._ _ class _ _ 4._ _ dict _ _ 特殊方法 1. _ _ subclasses _ _ () 2._ _ new _ _ (). _ _ init _ _ ()和 _ _ del _ _ () 3._ _ repr _ _ ()和 _ _ str _ _ () 4._ _ call _ _ () 5._ _ lt _ _ ()

  • Go语言实现运算符重载的方法详解

    目录 前言 使用 实现 总结 前言 先带来日常的 GScript 更新:新增了可变参数的特性,语法如下: int add(string s, int ...num){ println(s); int sum = 0; for(int i=0;i<len(num);i++){ int v = num[i]; sum = sum+v; } return sum; } int x = add("abc", 1,2,3,4); println(x); assertEqual(x, 10)

  • C++实践Time类中的运算符重载参考方法

    [项目-Time类中的运算符重载] 实现Time类中的运算符重载. class CTime { private: unsigned short int hour; // 时 unsigned short int minute; // 分 unsigned short int second; // 秒 public: CTime(int h=0,int m=0,int s=0); void setTime(int h,int m,int s); void display(); //二目的比较运算符

  • C++实践分数类中运算符重载的方法参考

    [项目-分数类中的运算符重载] (1)实现分数类中的运算符重载,在分数类中可以完成分数的加减乘除(运算后再化简).比较(6种关系)的运算. class CFraction { private: int nume; // 分子 int deno; // 分母 public: //构造函数及运算符重载的函数声明 }; //重载函数的实现及用于测试的main()函数 (2)在(1)的基础上,实现分数类中的对象和整型数的四则运算.分数类中的对象可以和整型数进行四则运算,且运算符合交换律.例如:CFrac

  • JavaScript之IE的fireEvent方法详细解析

    在IE中提供了一个fireEvent方法,顾名思义就是触发某个事件发生的意思.刚开始我以为是会跟平时使用onclick()一样,没想到最近在写javascript入门ppt的时候发现了,原来自己太自以为是了!看来还有很多javascript的细节没有掌握好啊! 现在根据自己的总结详细的记录下fireEvent方法的使用.fireEvent是IE提供的一种方法,msdn文档地址:http://msdn.microsoft.com/en-us/library/ms536423(v=vs.85).as

  • react-redux中connect()方法详细解析

    组件 React-Redux将所有组件分为两大类:展示组件(UI组件),容器组件 展示组件有以下几个特征: 只负责 UI 的呈现,不带有任何业务逻辑 没有状态(即不使用this.state这个变量) 所有数据都由参数(this.props)提供 不使用任何 Redux 的 API 容器组件有以下几个特征: 负责管理数据和业务逻辑,不负责 UI 的呈现 带有内部状态 使用 Redux 的 API 总结为一点: 展示组件负责 UI 的呈现,容器组件负责管理数据和逻辑 connect方法解析 下图是c

  • 修改mysql默认字符集的两种方法详细解析

    (1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,如 default-character-set = utf8    character_set_server = utf8 修改完后,重启mysql的服务,service mysql restart使用 mysql> SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8 复制代码 代码如下: +--------------------------+-----------

  • XAMPP安装与使用方法详细解析

    XAMPP 是一个把Apache网页服务器与PHP.Perl及MySQL集合在一起的安装包,允许用户可以在自己的电脑上轻易的建立网页服务器.使用 XAMPP 您可以轻松的在本机调试您的 PHP 程序.CMS以及 wordpress 博客程序.本文主要分享一下 XAMPP 的使用教程. XAMPP 使用方法1.下载 XAMPP 首先下载 XAMPP ,您可以在本页面下方提供的链接直接点入官方网站下载. 2.安装 XAMPP 我使用的是 XAMPP 的 Windows 版的安装包,下载后直接安装即可

  • a2sd+状态下应用程序丢失的解决方法详细解析

    这种情况,十有八九是SD存储卡的ext分区出错了,修复错误后重新开机即可重新启用a2sd+,找回原来安装的应用程序 同修复FAT分区一样,这个可以通过fsck来进行,运行命令从fsck_msdos变更为fsck就行了.不过如果你用的recovery版本有fix SD:ext这个选项的话,直接进入recovery选中修复就行了. 修复后重新启动手机,a2sd+就可以重新启用,空间不再不足,丢失的程序也能找回来了. 另外,容易导致这种问题出现的操作有如下几点需要注意:1.刷机完以后开机之后最好关机然

随机推荐