5.2.4 成员运算符重载函数和友元运算符重载函数的比较

(1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中有两个参数;对于单目运算符而言,成员运算符重载函数参数表中没有参数,而友元运算符重载函数参数表中有一个参数。

(2)双目运算符一般可以被重载为友元运算符重载函数或成员运算符重载函数,但有一种情况必须使用友元函数。

例如,如果将一个复数与一个整数相加,可用成员运算符重载函数"+"运算符:
Complex operator+(int a)
{
     return (real+a,imag);
}
若com和com1是类Complex的对象,则以下语句是正确的;
com = com+100; //正确,运算符+的左侧是类对象
这条语句被C++编译系统解释为:
com = com.operator(100);

由于对象com是运算符"+"的左操作数,所以它可以调用"+"运算符重载函数operator+,
执行结果是对象com的数据成员real被加上一个整数100.

然而,以下语句就不能工作了:
com = 100+com; //运算符+的左侧是整数
这条语句被C++编译系统解释为:
com = 100.operator(com);

由于运算符"+"的左操作数是一个整数100,而不是该类的对象。编译时将会出错,因为整数100不能调用成员运算符重载函数。

如果定义以下的两个友元运算符重载函数
friend Complex operator+(Complex com,int x) //运算符+的左侧是类的对象,右侧是整数
{
      return Complex(com.real+x,com.imag);
}

friend Complex operator+(int a,Complex com) //运算符+的左侧是整数,右侧是类的对象
{
      return Complex(a+com.real,com.imag);
}

当一个复数与一个整数相加时,无论整数出现在左侧还是右侧,使用友元运算符重载函数都能得到很好的解决。这就解决了使用成员运算符重载函数时,由于整数出现在运算符+的左侧而出现的错误。

//例5.7 使用友元运算符重载函数实现一个复数与整数的相加。

#include<iostream>
using namespace std;
class Complex{
public:
Complex(int r=,int i=)
{
real = r;
imag = i;
}
void print();
friend Complex operator+(int a,Complex &c2); //声明友元运算符重载函数,+的左侧是整数,右侧是类的对象
friend Complex operator+(Complex c1,int a);//声明友元运算符重载函数,+的右侧是整数,左侧是类的对象
private:
int real;
int imag;
};
Complex operator+(int a,Complex &c2) //定义友元运算符重载函数,+的左侧是整数,右侧是类的对象
{
Complex temp;
temp.real = a+c2.real;
temp.imag = c2.imag;
return temp;
}
Complex operator+(Complex c1,int a)//定义友元运算符重载函数,+的右侧是整数,左侧是类的对象
{
Complex temp;
temp.real = c1.real+a;
temp.imag = c1.imag;
return temp;
}
void Complex::print()
{
cout<<real<<"+"<<imag<<'i'<<endl;
}
int main()
{
Complex co1(,),co2(,),co3;
co1.print(); co3=+co1; //co3=operator+(100,co1);
co3.print(); co3=co2+; //co3=operator+(co2,100);
co3.print(); return ;
}

(3)成员运算符函数和友元运算符函数都可以用习惯方式调用,也可以用它们专用的方式调用。
表5.2 运算符函数调用形式
------------------------------------------------------------------------------------------
习惯调用形式 友元运算符重载函数的调用形式 成员运算符重载函数的调用形式
a+b operator+(a,b) a.operator+(b)
-a operator-(a) a.operator-()
a++ operator++(a,0) a.operator++(0)
------------------------------------------------------------------------------------------

(4)C++大部分运算符既可以说明为成员运算符重载函数,又可以说明为友元运算符重载函数。
一般而言,对于双目运算符,将它重载为友元运算符重载函数比重载为成员运算符函数便于使用。
对于单目运算符,则选择成员运算符重载函数比较好。
如果运算符所需要的操作数(尤其是第一个操作数)希望有隐式类型转换,则运算符重载必须使用
友元函数,而不能使用成员函数。

a.对于单目运算符,建议选择成员函数
b.对于运算符"=、()、[]、->"只能作为成员函数
c.对于运算符"+=、-=、/=、*=、/=、!=、~=、%=、<<=、>>=",建议重载为成员函数
d.对于其他运算符,建议重载为友元函数。

C++:成员运算符重载函数和友元运算符重载函数的比较的更多相关文章

  1. C++:运算符重载函数之友元运算符重载

    5.2.2 友元运算符重载函数 运算符重载函数一般采用两种形式定义: 一是定义为它将要操作的类的成员函数(简称运算符重载函数): 二是定义为类的友元函数(简称为友元运算符重载函数). 1.定义友元运算 ...

  2. C++:友元(非成员友元函数、成员友元函数、友元类)

    3.8  友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的 ...

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

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

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

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

  5. C++运算符重载形式——成员函数or友元函数

    运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...

  6. C++:友元运算符重载函数

    运算符重载函数:实现对象之间进行算数运算,(实际上是对象的属性之间做运算),包括+(加号).-(减号).*./.=.++.--.-(负号).+(正号) 运算符重载函数分为:普通友元运算符重载函数.成员 ...

  7. c++知识点总结--友元&运算符重载

    友元函数(不属于类) 可以访问类的私有变量,以及私有函数 友元函数在类内声明需要friend关键字,类外定义就不需要 友元函数可以直接在类内定义 友元函数必须包含对象指针   友元类(不适用继承,只适 ...

  8. C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载

    1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...

  9. C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象

    函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...

随机推荐

  1. 轻量级远程调用框架-Hessian学习笔记-Demo实现

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

  2. CentOS thrift python demo

    编辑接口文件 hellowworld.thrift service HelloWorld { string ping(), string say(1:string msg) } 编辑 server.p ...

  3. Oracle体系结构知识点的运用

    体系结构方面的优化问题: 设数据库很大,访问量非常高,共享池很小:这样共享池里面就无法存储很多解析过得sql语句,导致很多硬解析,这样数据库就非常缓慢.这个时候要加大共享池.如果是自动管理,就加大SG ...

  4. 鼠标驱动之-sys节点-input子系统

    首先需要了解sys节点和linux驱动编程的知识,在linux内核<linux/>下有着对应的实现.本例实现创建sys节点,外围程序通过input子系统控制鼠标位置. 第一步编写驱动代码, ...

  5. [css]兼容性

    div +input 输入框 , 在微信中  有问题 块级元素 行内元素

  6. 【nodejs】json value出现 undefined 将会无法解析 问题来了

    如果 value 的值就要 undefined  怎处理呢?

  7. iOS10 配置须知-b

    在iOS10中,如果你的App想要访问用户的相机.相册.麦克风.通讯录等等权限,都需要进行相关的配置,不然会直接crash.需要在info.plist中添加App需要的一些设备权限. NSBlueto ...

  8. Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld

    前言(Prologue) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Android ...

  9. android 自定义ratingbar 图片显示不全的解决方案

    在res/style中自定义评分条: <!-- 自定义评分条 --> <style name="roomRatingBar" parent="@andr ...

  10. 移植linux4.7.2与ubifs到jz2440

    前言 整个暑假跟着韦东山的视频和书籍移植了linux2.3.6到jz2440,现在自己尝试移植linux4.7.2到板子上,并使用ubifs文件系统代替旧的jffs2文件系统. 下载交叉编译工具链 工 ...