C++重载运算符

1.运算符重载的本质就是类对象调用一个运算符重载函数。比如说重载“+”运算符,其实是在调用operator+()这个函数。为支持多种运算,一个运算符可能有好几个同名的运算符重载函数,此时C++编译器会根据调用对象的类型决定调用哪个重载函数。例如在实现加法运算(+)时,C++编译器会根据+号左右两侧的元素类型,决定调用哪个重载函数。

例如:

 1 //.h文件
 2 #pragma once
 3 class Complex
 4 {
 5 public:
 6     Complex(int A=0,int B=0);
 7     ~Complex(void);
 8     Complex operator+(Complex&);
 9     Complex operator+(int&);
10     void printC(void);
11 
12 private:
13     int a;
14     int b;
15 };
16 
17 
18 //.cpp文件
19 #include "Complex.h"
20 #include<iostream>
21 
22 
23 Complex::Complex(int A,int B)
24 {
25     a=A;
26     b=B;
27 }
28 
29 
30 Complex::~Complex(void)
31 {
32 }
33 
34 Complex Complex::operator+(Complex& temp)
35 {
36     Complex c(this->a+temp.a,this->b+temp.b);
37     return c;
38 }
39 
40 Complex Complex::operator+(int& temp)
41 {
42     Complex c(this->a+temp,this->b);
43     return c;
44 }
45 
46 void Complex::printC(void)
47 {
48     std::cout<<a<<"+"<<b<<"i"<<std::endl;
49 }
50 
51 
52 //main函数
53 #include<iostream>
54 #include "Complex.h"
55 
56 using namespace std;
57 
58 
59 
60 int main()
61 {
62     int i=5;
63     Complex c1(1,2),c2(3,4);
64 
65     Complex c3=c1+c2;
66     c3.printC();
67 
68     Complex c4=c1+i;
69     c4.printC();
70     
71 
72     system("pause");
73     return 0;
74 }

2.C++中的重载运算符如果访问的是类的私有属性,除了把重载运算符函数写在类的里面作为成员函数,还可以将重载运算符函数写在类的外面,但此时重载运算符函数要被声明为友元函数,否则将无法访问类的私有属性。例如对上面的重载"+"运算符,如果将重载运算符函数写在类体的外面,可以写成:

friend Complex operator+(Complex& c1,Complex& c2);//在类体里面声明重载运算符函数为由原函数

//重载运算符函数在类体外的实现

Complex operator+(Complex& c1,Complex& c2)

{

    Complex c(c1.a+c2.a , c1.b+c2.b);

    return c;

 3.C++重载单目运算符,如"--"运算符时,由于"--"运算符有两种用法:--a(前置)  和  a++(后置)    所以重载"--"运算符时,写重载函数的时候就需要注意了,必须使重载函数的函数输入参数有所区别。可是"--"运算符写在类里面时,无须输入函数参数,为了区别前置"--"和后置"--"的重载函数,这时候我们就需要使用占位符了。

例如:

  1 //.h文件
  2 #pragma once
  3 class Complex
  4 {
  5 public:
  6     Complex(int A=0,int B=0);
  7     ~Complex(void);
  8     Complex operator+(Complex&);
  9     Complex operator+(int&);
 10     //friend Complex operator+(Complex& c1,Complex& c2);
 11 
 12     Complex& operator--(void);//前置--
 13     Complex operator--(int);//后置-- ,int是占位符
 14     void printC(void);
 15 
 16 private:
 17     int a;
 18     int b;
 19 };
 20 
 21 
 22 //.cpp文件
 23 #include "Complex.h"
 24 #include<iostream>
 25 
 26 
 27 Complex::Complex(int A,int B)
 28 {
 29     a=A;
 30     b=B;
 31 }
 32 
 33 
 34 Complex::~Complex(void)
 35 {
 36 }
 37 
 38 //********************************************重载"+"运算符****************************************
 39 Complex Complex::operator+(Complex& temp)
 40 {
 41     Complex c(this->a+temp.a,this->b+temp.b);
 42     return c;
 43 }
 44 
 45 Complex Complex::operator+(int& temp)
 46 {
 47     Complex c(this->a+temp,this->b);
 48     return c;
 49 }
 50 
 51 
 52 /*
 53 Complex operator+(Complex& c1,Complex& c2)
 54 {
 55     Complex c(c1.a+c2.a,c1.b+c2.b);
 56     return c;
 57 }
 58 */
 59 
 60 
 61 
 62 //********************************************重载"--"运算符****************************************
 63 //前置--
 64 Complex& Complex::operator--()
 65 {
 66     this->a--;
 67     this->b--;
 68 
 69     return *this;//返回的是一个引用,即this指针指向的对象本身
 70 }
 71 
 72 
 73 //后置--
 74 Complex Complex::operator--(int)
 75 {
 76     Complex temp=*this;
 77 
 78     this->a--;
 79     this->b--;
 80 
 81     return temp;
 82 }
 83 
 84 
 85 void Complex::printC(void)
 86 {
 87     std::cout<<a<<"+"<<b<<"i"<<std::endl;
 88 }
 89 
 90 
 91 //main函数
 92 #include<iostream>
 93 #include "Complex.h"
 94 
 95 using namespace std;
 96 
 97 
 98 
 99 int main()
100 {
101     int i=5;
102     Complex c1(1,2),c2(3,4);
103 
104 
105     --c2;
106     c2.printC(); //输出2+3i
107 
108     Complex c3=c2--;
109     c2.printC(); //输出1+2i
110     c3.printC(); //输出2+3i
111 
112     system("pause");
113     return 0;
114 }

4.C++重载"<<"运算符:

"<<"运算符的本质是ostream类的对象cout重载的一个函数,我们无法在ostream类里面将"<<"的重载函数添加为类ostream的成员函数,也无法在ostream类里面将"<<"的重载函数声明为ostream类的友元函数,因为我们根本无法得到ostream类的原码。所以只能在Complex类里面将"<<"的重载函数添加为类Complex的成员函数,或者将"<<"的重载函数声明为Complex类的友元函数。如果将"<<"运算符的重载函数写成是类Complex的成员函数,则调用的时候也是不对的。因为"<<"运算符是左结合的,它的重载函数本质上是ostream& operator<<(Complex&)的形式,如果写成类的成员函数形式只能是写在ostream类里面,肯定由cout这个对象来调用,即cout.operator<<(Complex对象)的调用形式,不可能是写在Complex类里面由Complex的类对象来调用(左结合性)。而我们前面提到过,我们无法得到ostream类的源码,无法将重载函数写在sstream类里面,因此,我们做出结论:”<<“运算符重载函数只能是声明为Complex类的友元函数。具体代码如下:

friend ostream& operator<<(ostream&,Complex&);//在Complex类体里面将operator<<函数声明为类Complex的由原函数

//operator<<友元函数的实现代码

ostream& operator<<(ostream& out,Complex& c)
{
    out<<c.a<<"+"<<c.b<<"i";
    return out;
}

 //上面的代码中之所以返回ostream&是为了<<可以串联使用。如cout<<c1<<"Hello"<<endl

 当被重载的运算符的左右两侧的操作数类型不一样的时候,最好用友元函数重载运算符,这样无论哪种类型的操作数写在前面,都能调用运算符重载函数。

5.C++里面不能重载的运算符有5个:

.(成员访问运算符)      

.*(成员指针访问运算符)      

 ::(域运算符)    

 sizeof(长度运算符)      

?:(条件运算符)

6.C++里面最好不要重载"&&"和"||"运算符,虽然在语法上它们支持重载,但重载的运算符无法实现原来运算符的短路效果。所谓的短路效果是指:a&&b,若果a表达式是假,则不必判断b表达式,直接判断(a&&b)为假。而重载“&&”运算符后,调用重载后的"&&"运算符本质上是执行a.operator&&(b)函数,它一定是先执行b表达式的,所以无法实现短路效果

原文地址:https://www.cnblogs.com/jswu-ustc/p/8350146.html