C++:成员运算符重载函数和友元运算符重载函数的比较
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++:成员运算符重载函数和友元运算符重载函数的比较的更多相关文章
- C++:运算符重载函数之友元运算符重载
5.2.2 友元运算符重载函数 运算符重载函数一般采用两种形式定义: 一是定义为它将要操作的类的成员函数(简称运算符重载函数): 二是定义为类的友元函数(简称为友元运算符重载函数). 1.定义友元运算 ...
- C++:友元(非成员友元函数、成员友元函数、友元类)
3.8 友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的 ...
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- C++运算符重载三种形式(成员函数,友元函数,普通函数)详解
首先,介绍三种重载方式: //作为成员函数重载(常见) class Person{ Private: string name; int age; public: Person(const char* ...
- C++运算符重载形式——成员函数or友元函数
运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...
- C++:友元运算符重载函数
运算符重载函数:实现对象之间进行算数运算,(实际上是对象的属性之间做运算),包括+(加号).-(减号).*./.=.++.--.-(负号).+(正号) 运算符重载函数分为:普通友元运算符重载函数.成员 ...
- c++知识点总结--友元&运算符重载
友元函数(不属于类) 可以访问类的私有变量,以及私有函数 友元函数在类内声明需要friend关键字,类外定义就不需要 友元函数可以直接在类内定义 友元函数必须包含对象指针 友元类(不适用继承,只适 ...
- C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载
1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...
- C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...
随机推荐
- RouterOS的MikroTik脚本从DNS更新IPSEC端的IP地址
#Script for changing IPSEC address when DNS changes. #Script will iterate through all peers looking ...
- exec 和 source的区别
source 就是让 script 在当前 shell 内执行.而不是产生一个 sub-shell 来执行.由exec 也是让 script 在同一个行程上执行,但是原有行程则被结束了. source ...
- AS3 - 数组Array的几个常用方法(附样例)
AS3 - 数组Array的几个常用方法(附样例) 2015-03-30 10:39发布:hangge浏览:241 Flex/Flash开发中,经常会使用到数组,下面总结了一些数组的常用方法. 1 ...
- C# 缓存学习总结
昨天整理了一下缓存的基本用法,和缓存依赖类 CacheDependency类的使用,今天整理一下缓存的数据库依赖类SqlCacheDependency 1.数据库依赖类SqlCacheDependen ...
- CentOS 6.3 配置 yum
ContOS 配置yum:1.cd /etc/yum.repos.d2.创建个任意目录,将所有文件移动到创建的目录中,除了CentOS-Media.repo3.编辑CentOS-Media.repov ...
- iOS中引用计数内存管理机制分析
在 iOS 中引用计数是内存的管理方式,虽然在 iOS5 版本中,已经支持了自动引用计数管理模式,但理解它的运行方式有助于我们了解程序的运行原理,有助于 debug 程序. 操作系统的内存管理分成堆和 ...
- 从零开始学ios开发(十二):Table Views(上)
这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messa ...
- 简单制作mib表
今天放假后第一天上班,将假前自学制作mib表的东西说一下. 在这里呢,我以世界-中国-上海-闵行这种包含关系介绍,感觉更容易理解. MIB file的开始和结束 所有的MIB file的都以DEFIN ...
- asp.net 中插入数据到access
这样报语法错误: insert into Menu_wx(userid,menutype,MenuID,menuname,MenuTitle,Url,Key,OrderValue,State) val ...
- FACL的使用
ACL的使用 ACL即Access Control List 主要的目的是提供传统的owner,group,others的read,write,execute权限之外的具体权限设置,ACL可以针对单一 ...