面向对象程序设计-运算符重载(2020-04-06)

当运算符作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义,合适的使用运算符重载可以提高代码的可读性!

运算符重载

重载运算符函数的参数数量于该运算符作用的运算对象数量一样多,但若该运算符重载函数是成员函数,则它的第一个运算对象绑定到this指针上,所以成员运算符函数的(显式)参数数量比运算对象的数量少一个。

Tips:
  • 1.对于一个运算符重载函数来说,它的运算对象不能全是内置类型,因为这样会导致原来正确的运算式不能得到正确的运算(二义性)。
  • 2.只能重载已有的运算符,不能发明新的运算符号。
  • 3.部分运算符不能被重载,见下图 :


    P1
  • 4.某些运算符不应该被重载(尽管它们被可以重载):逻辑与,逻辑或和逗号运算符,因为它们的运算对象求值顺序规则重载后不能被保留下来看,并且对"||"与"&&"来说,重载版本无法保留它们的短路求值属性。

成员函数还是非成员函数

当我们定义重载的运算符时,需要考虑是将其声明为类的成员函数还是非成员函数,下面给出《C++Primer》上给出的判断准则:

  • 1.赋值("=")、小标("[ ]")、调用("()")和成员访问箭头("->")运算符必须是成员。
  • 2.复合赋值运算符一般来说应该是成员,但并非必须,这一点与赋值运算符略有不同。
  • 3.改变对象状态的运算符或者与给定类型密切相关的运算符,如递增、递减和解引用运算符,通常应该是成员。
  • 4.具有对称性的运算符可能转换为任意一端的运算对象,例如算术、相等性、关系和位运算符等,因此它们通常应该是普通的非成员函数。

下面通过重载输入输出运算符来熟悉一下上面的内容:

重载输入输出运算符

#include <iostream>

using namespace std;

class Sales_data{
private:
    int a,b,c;
    //输出一个对象的数据成员不会改变对象的状态,所以这里用const Sales_data&
    friend ostream &operator<<(ostream &os,const Sales_data& a);
    //输入的值会改变对象的数据成员,所以这里不用const
    friend istream &operator>>(istream &is,Sales_data& a);
public:
    Sales_data():a(0),b(0),c(0){};
    Sales_data(int a,int b,int c):a(a),b(b),c(c){};
    ~Sales_data(){cout<<"~Sales_data"<<endl;}
};
ostream &operator<<(ostream &os,const Sales_data& a){
    os<<a.a<<" "<<a.b<<" "<<a.c<<endl;
    return os;
}
istream &operator>>(istream &is, Sales_data &a){
    int t;
    is >> a.a>>a.b>>t;
    //这个if语句用来检查输入是否成功
    if(is)
        a.c = a.a + a.b + t;
    //如果不成功,对象被赋予默认的状态
    else
        a = Sales_data();
}

int main()
{
    Sales_data b(1,2,3);
    cin>>b;
    cout<<b;
    return 0;
}

对于上面这段代码,我们可以看出,输入输出运算符必须是非成员函数,这两个运算符重载函数的第一个参数都是非常量流的引用,另外,它们都访问了Sales_data对象的私有成员,所以我们需要将它们声明为友元。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 3. 类设计者工具 3.1 拷贝控制 五种函数拷贝构造函数拷贝赋值运算符移动构造函数移动赋值运算符析构函数拷贝和移...
    王侦阅读 2,116评论 0赞 1
  • 运算符重载 当运算符作用域类类型对象时,可以通过运算符重载重新定义该运算符的含义,明智使用运算符重载能令我们的代码...
    土豆吞噬者阅读 2,677评论 0赞 0
  • 基本上我们进行运算符重载时有两种形式,类内的运算符重载和顶层函数位置的运算符重载。 操作符重载指的是将C++提供的...
    飞扬code阅读 1,818评论 0赞 4
  • C++语言的一个很有意思的特性就是除了支持函数重载外还支持运算符重载,原因就是在C++看来运算符也算是一种函数。比...
    欧阳大哥2013阅读 2,803评论 0赞 8
  • C++类和对象 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心...
    863cda997e42阅读 800评论 0赞 4

友情链接更多精彩内容