C++ 操作符重载形式——成员函数 or 友元函数

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

对操作符重载,我们需要坚持四项基本原则:
(1)不可臆造运算符。
(2)运算符原有操作数的个数、优先级和结合性不能改变。
(3)操作数中至少一个是自定义类型。
(4)保持重载运算符的自然含义。

一般来说,C++ 操作符重载可采用成员函数和友元函数,二者都可以访问类的私有成员,那么该采用哪一种呢?

首先看一下二者的区别。

  • 当重载为成员函数时,会隐含一个 this 指针;当重载为友元函数时,不存在隐含的 this 指针,需要在参数列表中显示添加操作数。
  • 当重载为成员函数时,只允许右参数的隐式转换;当重载为友元函数时,能够接受左参数和右参数的隐式转换。

如下代码:

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

因为 CString 的构造函数参数为一个char*,所以如果采用友元形式的operator +(const CString&, const CString&),那么char+CStringCString+char都能正常工作;而如果采用成员函数形式CString::operator+(const CString& rhs),则只能接受CString+char,如果执行char+CString则会编译出错。我们往往习惯CString+charchar+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;
}

参考文献

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

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值