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. SQLserver关于教学楼中教室在某个时间段是否被占用的数据库设计

    需求:关于教学楼中教室在周几某个时间段是否被占用的数据库设计 具体代码如下: -------------------教学楼维度 CREATE TABLE TeacBuild ( tbID int no ...

  2. Log.i()的用法

    2011-04-16 09:44 17486人阅读 评论(4) 收藏 举报 androidlayoutbuttonstringencodingeclipse 在调试代码的时候我们需要查看调试信息,那我 ...

  3. 从零开始学ios开发(十二):Table Views(上)

    这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messa ...

  4. 深入理解ThreadLocal(一)

    Android里,在不同的线程(假设子线程已经创建了Looper)中创建Handler时,并不需要显式指定Looper,系统能自动找到该线程自己的Looper.不同线程的Looper相互独立,之所以能 ...

  5. Unity Camera属性

    Camera属性 1.Clear Flags 清除标记:决定屏幕的那部分将被清除.当使用多个相机来描绘不同的游戏景象时,利用它是非常方便的. 2.Background 背景:在镜头中的所有元素描绘完成 ...

  6. C++ 字符串相关函数

    <转>自:http://zhidao.baidu.com/question/173202165.html 首先就是memcpy表头文件: #include <string.h> ...

  7. Careercup - Facebook面试题 - 5729456584916992

    2014-05-02 00:59 题目链接 原题: Given a normal binary tree, write a function to serialize the tree into a ...

  8. axure7.0 汉化包下载

    下载地址:http://files.cnblogs.com/files/feijian/axure7.0%E4%B8%AD%E6%96%87%E8%AF%AD%E8%A8%80%E6%B1%89%E5 ...

  9. java 把URL中的中文转换成utf-8编码

    private static final String QUERY = "餐饮"; String sr = URLEncoder.encode(QUERY); System.out ...

  10. 移动端页面使用rem来做适配

    文/九彩拼盘(简书作者)原文链接:http://www.jianshu.com/p/eb05c775d3c6著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. rem介绍 rem(font ...