C++中的操作符重载

原创 2018年04月16日 19:57:21

首先说句,为什么要使用操作符重载呢?

其实我们使用别人编写好的类时往往不用考虑,你不用查看cout << a; 中<<是如何重载的,就可以自如地在屏幕上输出或在文件中写入字符,字符串,数字,乃至指针地址,可当我们自己设计类给自己或其他程序员使用时就不得不考虑了。

现在假设我设计一个时间类,初始声明代码如下

class Time
{
private:
	int hours;
	int minutes;
public:
	Time(int h = 0, int m = 0);
};

这里就只有两个成员变量和一个构造函数,实际重载时会有以下几种情况:

1、二元操作符的两个参数均为Time类对象:

这时我们有两种选择,第一种就是常见的成员函数实现

Time Time::operator +(const Time &t) const
{
	Time sum;
	sum.minutes = minutes + t.minutes;
	sum.hours = hours + t.hours + sum.minutes/60;
	sum.minutes %= 60;
	return sum;
}
第二种就是使用友元函数来实现:
Time operator+(const Time &t1, const Time &t2)
{
	Time sum;
	sum.minutes = t1.minutes + t2.minutes;
	sum.hours = t1.hours + t2.hours + sum.minutes/60;
	sum.minutes %= 60;
	return sum;
}

当然,我们要在类声明中添加对应的函数声明,修改类声明代码:

class Time
{
private:
	int hours;
	int minutes;
public:
	Time(int h = 0, int m = 0);
        Time operator+ (const Time & t)const; 
        //friend Time operator+ (const Time & t1, const Time & t2);
};

这里需要注意的就是这两种不能同时定义,否则编译时会有二义性错误,因为当你在其它文件中使用加法时:

Time coding(2,40);
Time fixing(5,55);
Time total;
total = coding + fixing;

编译器将不知道要匹配哪种方法。那么就有人问了,为啥还要有友元函数这种方法呢?是闲着没事做吗?当然不是,我们来看第二种情况。


2、二元操作符的一个参数为Time类对象:

现在呢,其他人给我提供的时间对象是一个double型的变量,单位呢是小时,我需要整合运算,理论上来说只需要重载操作符重载函数即可,也就是加入声明代码:

Time operator+ (double n)const;

以及对应的实现:

Time Time::operator+(double n) const
{
	Time result;
        int i = n;
        n = n - i;

        result.minutes = minutes + n * 60;
        result.hours = hours + i + result.minutes /60;
	result.minutes %= 60;

	return result;
}

到这里,假设有个Time类的实例A,计算A+1.5是没问题的,可计算1.5+A是不行的,因为左边的操作数不是调用对象,这里就需要非成员函数,而且还要能访问类的私有成员,于是友元函数就产生了,它在类中声明,但不是成员函数,但又能访问私有成员。所以还需要在类中声明:

friend Time operator+ (double n, const Time & t);

实现文件中定义:

Time operator+ (double n, const Time & t)
{
	Time result;
        int i = n;
        n = n - i;

        result.minutes = t.minutes + n * 60;
        result.hours = t.hours + i + result.minutes /60;
	result.minutes %= 60;

	return result;
}

当然有更简单的方法:

Time operator+ (double n, const Time & t)
{
    return t * n;
}

这里友元函数和成员函数都需要定义,因为参数顺序不同。

成员函数对应A+1.5,友元函数对应1.5+A。


3、综合使用:

综上,要实现Time类两两相加或加上一个double类型,要2个成员函数和1个友元函数,那有没有简单点的实现呢?

有的,那就是利用类的隐式转换。首先看:

int a = 3.33;

这是可行的,C++将double型的自动转换为int型,假如两种类型互相兼容的话,C++都会自动转换。

那么,当我们在类声明中加入接受一个参数的构造函数时,这个构造函数可以作为转换函数来转换类型。加入声明:

Time (double dhrs);

实现代码:

Time::Time(double dhrs)
{
   int i = dhrs;
   dhrs= dhrs - i;

   hours = i;
   minutes = dhrs * 60;
 }

那么下面的代码是合法的:

Time planning;
planning = 1.5;

程序将使用构造函数Time( double ) 来创建一个临时Time对象,参数即为1.5。随后,采用逐成员赋值的方法将该临时对象的内容复制到planning中。

notes:

当然,这种特性是可以关闭的,当你要防止意外的自动转换时,可以用关键字explicit来关闭该特性,也就是,声明为:

explicit Time (double dhrs);

显式转换则不受影响。使用转换函数还可以将Time对象隐式转换为double型,关于转换函数更详细地可以再单独了解学习。

现在再回过头来看加法的实现,首先将之前的3个函数去掉,在类中声明如下的友元函数:

friend Time operator+ (const Time & t1, const Time & t2);

在实现文件中添加实现代码:

Time operator+ (const Time & t1, const Time & t2)
{
	Time sum;
	sum.minutes = t1.minutes + t2.minutes;
	sum.hours = t1.hours + t2.hours + sum.minutes/60;
	sum.minutes %= 60;
	return sum;
}

这时候就可以实现:

Time A, B;
A + B;
A + 1.5;
1.5 + A;

因为他们被解释为operator+(A, B);    operator+(A, 1.5);    operator+(1.5, A);

在这些函数中参数的double类型被自动隐式转换为Time类,然后运算。


好了,关于操作符重载就说到这里了,完成,如有错误,还望不吝赐教。



用一个例子来理解c++中的重载

格式:operatorop(argument-list) 例:operator+(),表明重载“+”运算符,其中op必须为C++运算符,如@不是c++中的符号,则不能定义为重载。 下面用两个时间的类对...
  • sinat_36436112
  • sinat_36436112
  • 2017-05-23 15:34:10
  • 101

C++编程实例——实现简单的时间加减运算

C++是面向对象的程序语言,区别我们的C语言,具体编程首先要定义一个类,类中包含私有成员以及公有成员两部分,私有成员主要是变量,公有成员主要是方法,另外还需要另外的.cpp程序来实现这些公有方法,以及...
  • qicheng777
  • qicheng777
  • 2017-06-04 16:59:33
  • 2230

C++运算符重载(11) - 重载<<和>>操作符

运算符 “>”用于流输出。 在开始重载这些操作符之前,必须注意下面的事项: 1) cout是输出类的对象,而cin是输入类的对象 2) 这些操作符必须重载为全局函数。如果想要让它们可以访问私有成员,...
  • shltsh
  • shltsh
  • 2015-05-27 00:11:16
  • 1342

所有C++操作符重载的例子

1.[ ]操作符重载 C++语言规定:“[ ]”只能作为类的成员函数进行重载。 “[ ]”是C++中的下标运算符,对于数组或指针来说,下表运算的语义是确定的,不能进行重载。因此,如果看到一个运算...
  • chijianxingfeng
  • chijianxingfeng
  • 2013-04-30 13:04:06
  • 2522

c++课件之操作符重载

  • 2014年10月17日 17:51
  • 612KB
  • 下载

C++ STL 基础及应用(2) 模板与操作符重载

模板是 C++ 语言中重要的概念。它提供了一种通用的方法来开发重用的代码,即以创建参数化的 C++ 类型。 本章将阐述一些具体的 STL 模板思想,并简单介绍操作符重载与模板的联系。 文中将给出一个简...
  • Raito__
  • Raito__
  • 2016-05-22 17:13:08
  • 2794

C++ 重载操作符 operator

参数个数的限定     非成员函数:   单目运算符:参数表中只有一个参数;   双目运算符:参数表中只有两个参数       成员函数:   单目运算符:参数表中没有参数; ...
  • fenhong91
  • fenhong91
  • 2017-02-07 09:55:43
  • 1441

C++主要操作符重载的定义和总结

一、输出操作符的重载     ostream& operator    {os     return os;}    为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类...
  • lzkIT
  • lzkIT
  • 2012-07-15 23:27:27
  • 5044

重学C++ (九) 重载操作符与转换

1.重载操作符必须具有至少一个类类型或枚举类型的操作数(内置类型的操作符含义不能改变);2.除了函数调用操作符operator()之外,重载操作符时不能使用默认实参;3.重载之后&&, ||不再具备短...
  • jiange_zh
  • jiange_zh
  • 2016-01-25 14:50:36
  • 764

C++中的重载运算符、继承、封装、多态讲解(进阶篇)

上次我们说到C++语言中的面向对象基本概念,那就是什么是类什么是对象,他们之间的关系是什么,本篇博文我们来说说,C++语言中重要的几个机制。(面试也经常会被问到这些知识点) 一个类可以派生自多...
  • songkai320
  • songkai320
  • 2016-07-15 10:16:31
  • 1300
收藏助手
不良信息举报
您举报文章:C++中的操作符重载
举报原因:
原因补充:

(最多只允许输入30个字)