C++之运算符重载

来源:互联网 发布:java中文分词器 编辑:程序博客网 时间:2024/06/15 22:05

学习借鉴网址:
operator overloading


非成员函数重载运算符


  • 定义运算符重载函数后,在参数、 运算符匹配的情况下调用运算符重载函数。
  • 在以下代码调用中: f1 + f2等同于operator+(f1, f2)
    注意:在非成员函数重载中,只能访问操作public成员
#include <iostream>using namespace std;class F{public:    int a;};int operator+(F &f1, F& f2){    return f1.a + f2.a;}int main(int argc, char *argv[]){    F f1;    f1.a = 1;    F f2;    f2.a = 2;    cout << f1 + f2 << endl;    return a.exec();}

友元运算符重载


  • 友元是关键字,友元运算符重载不是重载友元,而是使用友元来重载运算符
  • 相对于普通运算符重载函数,友元可以访问形参类型中的私有成员
  • 在双目运算符中,友元运算符重载有两个参数,友元中没有this指针
  • 当一个复数与一个整数相加时,无论整数出现在左侧还是右侧,使用友元运算符重载函数都能得到很好的解决。
  • 在以下代码调用中: stu + stu2等同于operator+(stu, stu2)
#include <iostream>using namespace std;class Student{private:    int id;public:    Student(int id_t){        id = id_t;    }    Student(){}    friend int operator+(Student& stu, Student& stu2);};int operator+(Student& stu, Student& stu2){    return stu.id + stu2.id;}int main(int argc, char *argv[]){    Student stu(1);    Student stu2(2);    cout << stu + stu2 <<endl;    return 0;}

成员函数运算符重载


  • 成员函数运算符重载相对与友元运算符重载,要少一个形参,即this指针。
  • 在以下代码调用中: stu2 = stu;等同于stu2.operator=(stu);
#include <iostream>using namespace std;class Student{private:    int id;public:    Student(){}    Student(int id):id(id){}    Student& operator=(Student& stu2){        this->id = stu2.id;        return *this;    }    int getId(){        return id;    }};int main(int argc, char *argv[]){    Student stu(10);    Student stu2(2);    stu2 = stu;    cout << stu2.getId() << endl;    return 0;}

总结


  1. C++大部分运算符既可以用成员运算符重载函数,又可以用友元运算符重载函数。
  2. 如果运算符所需要的操作数(尤其是第一个操作数)希望有隐式类型转换,则运算符重载必须使用友元函数,而不能使用成员函数。
  3. 对于单目运算符,建议选择成员函数重载
  4. 对于双目运算符,一般而言选择友元运算符重载函数较好
  5. 对于运算符”=、()、[]、->”只能作为成员函数
  6. 对于运算符”+=、-=、/=、*=、/=、!=、~=、%=、<<=、>>=”,建议选择成员函数重载
  7. 对于其他运算符,建议选择友元运算符重载函数较好

问题


在C++运算符重载这一章中一直有一个让我想不明白的问题,

赋值运算符为什么不能友元重载?在使用重载运算符时,怎么选择友元运算符重载函数和成员函数运算符重载?

我有浏览过很多博主写的文章,但仍然没有找到想要的答案,我摘录一些博主的在其他论坛、文章中的见解:

  1. []、()、->、=这几个运算符如果要重载,为什么必须重载为成员函数而不能重载为友元?
    youyou1912:为什么呢? 因为
    C++不允许全局重载这几个操作符.
    C++也没有提供调用对象作为参数放进去.

    struct A;void operator()(A*, int);// 非法
  2. 关于C++运算符重载 成员函数和友元函数的区别
    Falleyes:一楼正解,那个网址给的好牛。
    全局版本的自动类型(友元)转换可以针对左右任意操作数,而成员版本(成员)必须保证左操作数已经处于正确的形式。
    比如成员函数:

    N operator+(const N&n) const{   return N(i+n.i);   //函数调用可以计算a+1,但是无法计算1+a   //友元版本包括两个参数,所以可以计算a+1,也可以计算1+a}
  3. 运算符重载:成员函数与非成员函数?
    If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!

    But what if the first operand is not a class? There’s a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.