C++运算符重载形式——成员函数or友元函数
运算符重载是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友元函数的更多相关文章
- C++运算符重载三种形式(成员函数,友元函数,普通函数)详解
首先,介绍三种重载方式: //作为成员函数重载(常见) class Person{ Private: string name; int age; public: Person(const char* ...
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- 重载运算符:类成员函数or友元函数
类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...
- C++运算符重载(成员函数方式)
一.运算符重载 C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.如果将C++中这些现存的运算符直接作用于用户自定义的类型数据上,会得到什么样 ...
- C++ //多态 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 //动态多态:派生类和虚函数实现运行时多态
1 //多态 2 //静态多态:函数重载 和 运算符重载 属于静态多态 ,复用函数名 3 //动态多态:派生类和虚函数实现运行时多态 4 5 //静态多态和动态多态的区别 6 //静态多态的函数地址早 ...
- C++重载(主要介绍使用友元函数重载)
重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一 ...
- VC++的函数指针和回调函数 及友元函数
什么是函数指针 函数指针是指向函数的指针变量.也就是说,它是一个指针变量,而且该指针指向一个函数. 对于指针变量来说,它的值是它指向的变量的地址.举个例子:指针变量pi是指向一个整型变量i的指针,则变 ...
- C++运算符重载为成员函数
#include<iostream> using namespace std; class Complex{ public: Complex(double r=0.0,double i=0 ...
- C++运算符重载(友元函数方式)
我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函 ...
随机推荐
- hadoop组件概念理解
一.HADOOP 二.HIVE 三.SQOOP 1.来由和作用 sqoop由一些封装好的MR程序的jar包构成,后演变成框架,但sqoop只有map任务没有reduce任务. 用于 hdfs.hive ...
- kubeadm 线上集群部署(二) K8S Master集群安装以及工作节点的部署
PS:所有机器主机名请提前设置好 在上一篇,ETCD集群我们已经搭建成功了,下面我们需要搭建master相关组件,apiverser需要与etcd通信并操作 1.配置证书 将etcd证书上传到mast ...
- LEETCODE —— Unique Paths II [Dynamic Programming]
唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...
- [shell] 一次性赋值多个变量
管道符是fork子进程,子进程的变量无法传回父进程 [root@XM-v106 ~]# echo "1 2 3" | read a b c;echo $a [root@XM-v10 ...
- spring-session实现分布式集群session的共享(转)
原文: https://www.cnblogs.com/youzhibing/p/7348337.html HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保 ...
- HDU 1556 Color the ball (一维树状数组,区间更新,单点查询)
中文题,题意就不说了 一开始接触树状数组时,只知道“单点更新,区间求和”的功能,没想到还有“区间更新,单点查询”的作用. 树状数组有两种用途(以一维树状数组举例): 1.单点更新,区间查询(即求和) ...
- unload没有用
今天下午测试了unload这个事件包括beforeunload <script type="text/javascript"> window.addEventListe ...
- Beta阶段中间产物【欢迎来怼】
一.版本控制 ①Git地址:https://git.coding.net/tianjiping/Android-tianjiping.git ②check in次数:7次. ③成员代码贡献 因为阚博文 ...
- 20162314 《Program Design & Data Structures》Learning Summary Of The Seventh Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Seventh Wee ...
- roject ..\appcompat_v7 is missing. Needed by eclipse 转AS项目时遇到的问题
参考的 http://www.cnblogs.com/vanezkw/p/4182917.html 去转换项目, 在第一步的时候就遇到问题 ,提示 missing 而那个又是兼容包 解决方法:项目右键 ...