运算符重载是C++多态的重要实现手段之一。通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能。

运算符重载的我们需要坚持四项基本原则:

(1)不可臆造运算符;

(2)运算符原有操作数的个数、优先级和结合性不能改变;

(3)操作数中至少一个是自定义类型;

(4)保持重载运算符的自然含义。

一般来说,C++运算符重载可采用成员函数和友元函数,二者都可以访问类的私有成员,那么该采用哪一种呢?首先看一下二者的区别。

(1)当重载为成员函数时,会隐含一个this指针;当重载为友元函数时,不存在隐含的this指针,需要在参数列表中显示地添加操作数。

(2)当重载为成员函数时,只允许右参数的隐式转换;当重载为友元函数时,能够接受左参数和右参数的隐式转换。

如下代码:

class CString{
public:
    CString(char* str);
private:
    char* m_pStr;
};

因为CString的构造函数参数为一个char*,所以如果采用友元形式的operator +(const CString&, const CString&),那么char+CString和CString+char都能正常工作;而如果采用成员函数形式CString::operator+(const CString& rhs),则只能接受CString+char,如果执行char+CString则会编译出错。我们往往习惯CString+char和char+CString都应该被接受。需要注意的是,隐式转换由于临时变量的增加往往效率不高。如果应用程序对效率要求较高,针对以上类,建议选择定义多个运算符的友元重载版本:

CString& operator +(const CString&, const CString&);
CString& operator +(const char*, const CString&);
CString& operator +(const CString&, const char*);

一般而言,对于双目运算符,最好将其重载为友元函数;而对于单目运算符,则最好重载为成员函数。

但是也存在例外情况。有些双目运算符是不能重载为友元函数的,比如赋值运算符=、函数调用运算符()、下标运算符[]、指针运算符->等,因为这些运算符在语义上与this都有太多的关联。比如=表示“将自身赋值为…”,[]表示“自己的第几个元素”,如果将其重载为友元函数,则会出现语义上的不一致。

还有一个需要特别说明的就是输出运算符<<。因为<<的第一个操作数一定是ostream类型,所以<<只能重载为友元函数,如下:

friend ostream& operator <<(ostream& os, const Complex& c);
ostream& operator <<(ostream& os, const Complex& c){
    os << c.m_Real << “+” << c.m_Imag << “i” << endl;
    return os;
}

参考文献

[1]李健.编写高质量代码:改善C++程序的150个建议.第一版.北京:机械工业出版社,2012.1:131-134

C++运算符重载形式——成员函数or友元函数的更多相关文章

  1. C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

    首先,介绍三种重载方式: //作为成员函数重载(常见) class Person{ Private: string name; int age; public: Person(const char* ...

  2. C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...

  3. 重载运算符:类成员函数or友元函数

    类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...

  4. C++运算符重载(成员函数方式)

    一.运算符重载 C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.如果将C++中这些现存的运算符直接作用于用户自定义的类型数据上,会得到什么样 ...

  5. C++ //多态 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 //动态多态:派生类和虚函数实现运行时多态

    1 //多态 2 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 3 //动态多态:派生类和虚函数实现运行时多态 4 5 //静态多态和动态多态的区别 6 //静态多态的函数地址早 ...

  6. C++重载(主要介绍使用友元函数重载)

    重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一 ...

  7. VC++的函数指针和回调函数 及友元函数

    什么是函数指针 函数指针是指向函数的指针变量.也就是说,它是一个指针变量,而且该指针指向一个函数. 对于指针变量来说,它的值是它指向的变量的地址.举个例子:指针变量pi是指向一个整型变量i的指针,则变 ...

  8. C++运算符重载为成员函数

    #include<iostream> using namespace std; class Complex{ public: Complex(double r=0.0,double i=0 ...

  9. C++运算符重载(友元函数方式)

    我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函 ...

随机推荐

  1. SICP读书笔记 3.4

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  2. Netty源码分析第2章(NioEventLoop)---->第7节: 处理IO事件

    Netty源码分析第二章: NioEventLoop   第七节:处理IO事件 上一小节我们了解了执行select()操作的相关逻辑, 这一小节我们继续学习select()之后, 轮询到io事件的相关 ...

  3. Netty源码分析第5章(ByteBuf)---->第7节: page级别的内存分配

    Netty源码分析第五章: ByteBuf 第六节: page级别的内存分配 前面小节我们剖析过命中缓存的内存分配逻辑, 前提是如果缓存中有数据, 那么缓存中没有数据, netty是如何开辟一块内存进 ...

  4. 升级salt导致进程kill问题记录

    重启salt-minion导致由salt启动的进程kill问题排查 作者:耀耀 blog:https://www.liuyao.me 环境 服务器系统为centos6及centos7 服务器服务进程都 ...

  5. 通过exp命令对Oracle数据库进行备份操作(提供两种情况的备份:备份本地,备份远程的数据库)

    exp 用户名/密码@数据库所在ip地址:数据库端口号/数据库的service-name file=存储到的位置 这个是能成功的 http://www.2cto.com/database/201402 ...

  6. pairwork(黄敬博12061156和黄伟龙12061172)

    结对编程: 结对编程的优缺点: 优点: 1.相互督促,共同为了完成目标而努力: 2.节省时间,通过将疑难问题分开解决,共同讨论,实现了更高效的时间利用率: 3.能力互补,提高代码的质量,同时也提高了测 ...

  7. Jsp----注册登陆

    一.需求分析 目前99%的网站都会有用户的登陆注册界面(用户就是一切嘛).其需求可想而知. 二.设计过程及所查寻资料 通过寻找上课老师所给予的课件,搜寻相关内容:目前以获取相关有java web关于w ...

  8. 文献:Technology-related Disasters:A Survey toward Disaster-resilient Software Defined Networks

    DISASTER的定义和影响(本文中) 定义范围: 自然灾害,比如洪水.地震等造成一定范围类的节点故障: 恶意攻击,DDOS攻击或者电磁脉冲攻击造成节点故障: 技术相关的问题,配置错误或者误操作等: ...

  9. WPF自学入门(十二)WPF MVVM模式提取函数

    我们平时在写代码时为了不重复写代码,会进行复制代码或者写通用方法.今天我们就来把上传做的函数提取成为通用的方法调用.把上次写的函数提取为两个主要的文件:ObserableObject和RelayCom ...

  10. C++编译与链接(2)-浅谈内部链接与外部链接

    发现每次写技术博客时,都会在文章开头处花费一番功夫 ...从前,有一个程序员....他的名字叫magicsoar 为什么有时会出现aaa已在bbb中重定义的错误? 为什么有时会出现无法解析的外部符号? ...