运算符重载的两种方式
1 基本概念
基础

方式
- 将运算符重载为类的成员函数。
- 重载运算符函数,并声明为类的友元。
规则
重载后的运算符必须至少有一个操作数是用户定义的类型,这是为了防止程序员为标准类型重载运算符,可以确保程序正确运行。
不能修改运算符的优先级,不能违反运算符原本的运算规则。例如在重载加号时,不能提供两个形参(友元除外),例如下面的这种重载方式就是不被允许的;因为加法是一种双目运算符。在重载为类的成员函数后,加法运算的第一项应该是调用函数的一个对象。所以在运算符重载时,参数表中的参数数目应该是重载运算符的操作数减1。
1
| Time operator+(const Time &t1,const Time &t2) const;
|
- 不能创造新的运算符,例如不能定义operator**()运算符;
- 不能重载以下运算符;
1 2 3 4 5
| .:成员运算符 .*:成员指针运算符 :: :作用域运算符 ?::条件运算符 siezof:sizeof运算符。
|
- 很多运算符可以通过成员或者非成员函数进行重载,但是以下四种只能通过成员函数进行重载;
1 2 3 4
| =:赋值运算符; ( ):函数调用运算符; [ ]: 下标运算符 ->:通过指针方位类成员的运算符。
|
- 自增运算符(++)与自减运算符(–)由于自增和自减运算符是单目运算符,在重载时应该是没有参数的,但是又有前置与后置之分,例如++i与i++。为了隽星区分,C++做了规定;
1 2
| Time operator++() Time operator++(int)
|
2 成员函数重载
成员函数重载格式
- 将操作符重载为成员函数。
- 此时类的对象作为操作符的第一个操作数。流输入输出运算符无法通过这样的方式重载,因为对象本身应该作为第二个操作数,只能通过友元函数的方式对操作进行重载。
1 2 3 4 5 6 7
| class MyString{ public: MyString& operator=(const MyString &b); MyString& operator+=(const MyString &b); }
|
3 友元重载
友元的格式
C++中友元有三种,分别是友元函数,友元类,友元成员函数,这里介绍的是友元函数。
- 创建友元函数的第一步是声明,友元函数的声明放在类的声明中,并且在前面加上friend关键字。例如;
1
| friend ostream& operator<<(ostream &os, const Time &t);
|
- 第二步是定义友元,友元可以直接在声明的时候进行定义,即内联的定义。也可以定义在类外,定义在类外时,不需要加类作用域运算符,也不需要有friend关键字。
1 2 3 4 5 6
| ostream & operator<<(ostream &os, const Time &t) { os << "hours:" << t.hours << " " << "mintues:" << t.mintues << " "; return os; }
|
友元使用
与普通的运算符重载成员函数一样,友元也可以直接调用
1 2
| cout<<time1<<time2; operator<<(operator<<(cout,time1),time2);
|
4 实例——MyString的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#include <iostream> #include <cstring> using namespace std;
class MyString { private: char * str; int length; public: int size ()const { return length; }; char* getstr()const{ return str; } MyString(); MyString(const char*); MyString(const MyString& b);
MyString& operator=(const MyString &b); MyString& operator+=(const MyString &b); bool operator<(const MyString &b); char& operator[](const int &index) const ; friend ostream& operator<<(ostream& ,const MyString &b); ~MyString(); };
MyString::MyString() { str = new char[1]; str[0]='\0'; length = 0; }
MyString::MyString(const char* b){ if(b){ length = strlen(b); str = new char[length+1]; strcpy(str,b); } else{ MyString(); } } MyString::MyString(const MyString&b){ length = b.size(); if(length>0) str = new char[length+1]; else MyString(); }
MyString& MyString::operator=(const MyString &b){ if(&b == this){ return *this; } delete[] str; length = b.size(); str = new char[length + 1]; strcpy(str,b.getstr()); return *this; }
MyString& MyString::operator+=(const MyString&b){ if(b.size()==0){ return *this; } char* temp = new char[length+b.length+1]; strcpy(temp,str); strcat(temp,b.getstr()); delete[] str; str = temp; return *this; }
char& MyString::operator[](const int &index)const { if(index>length)return str[length]; return str[index]; }
bool MyString::operator<(const MyString &b){ for(int i=0;i<length;i++){ if(i>b.size())return false; if(b[i]>str[i])return true; if(b[i]<str[i])return false; } return true; }
MyString::~MyString() { delete[] str; }
ostream& operator<<(ostream &out,const MyString&b){ out<<b.getstr(); return out; }
int main() { MyString s1,s2="123",s3,s4="456"; s3=s2; s1=s2; s1+=s1; cout<<s1<<endl; cout<<s2<<endl; cout<<s3<<endl; cout<<(s3<s4)<<endl; cout<<endl; return 0; }
|
5 实例——complex的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #include <iostream> using namespace std; class complex{ public: complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }; public: friend complex operator+(const complex & A, const complex & B); friend complex operator-(const complex & A, const complex & B); friend complex operator*(const complex & A, const complex & B); friend complex operator/(const complex & A, const complex & B); friend istream & operator>>(istream & in, complex & A); friend ostream & operator<<(ostream & out, complex & A); private: double m_real; double m_imag; };
complex operator+(const complex & A, const complex &B){ complex C; C.m_real = A.m_real + B.m_real; C.m_imag = A.m_imag + B.m_imag; return C; }
complex operator-(const complex & A, const complex &B){ complex C; C.m_real = A.m_real - B.m_real; C.m_imag = A.m_imag - B.m_imag; return C; }
complex operator*(const complex & A, const complex &B){ complex C; C.m_real = A.m_real * B.m_real - A.m_imag * B.m_imag; C.m_imag = A.m_imag * B.m_real + A.m_real * B.m_imag; return C; }
complex operator/(const complex & A, const complex & B){ complex C; double square = A.m_real * A.m_real + A.m_imag * A.m_imag; C.m_real = (A.m_real * B.m_real + A.m_imag * B.m_imag)/square; C.m_imag = (A.m_imag * B.m_real - A.m_real * B.m_imag)/square; return C; }
istream & operator>>(istream & in, complex & A){ in >> A.m_real >> A.m_imag; return in; }
ostream & operator<<(ostream & out, complex & A){ out << A.m_real <<" + "<< A.m_imag <<" i ";; return out; } int main(){ complex c1, c2, c3; cin>>c1>>c2; c3 = c1 + c2; cout<<"c1 + c2 = "<<c3<<endl; c3 = c1 - c2; cout<<"c1 - c2 = "<<c3<<endl; c3 = c1 * c2; cout<<"c1 * c2 = "<<c3<<endl; c3 = c1 / c2; cout<<"c1 / c2 = "<<c3<<endl; return 0; }
|
6 实例——MyTime的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| #ifndef MYTIME_H #define MYTIME_H #include <iostream> using namespace std; class Time { private: int hours; int mintues; public: Time(); Time(int h, int m = 0); Time(const Time &); ~Time(); void AddMin(int m); void AddHour(int h); void reset(int h = 0, int m = 0); void Time::show() const { cout << "hours:" << hours << " " << "mintues:" << mintues << " "; } Time operator+(const Time &t) const; Time operator-(const Time &t) const; Time operator*(double n) const; friend Time operator*(double n, const Time &t) { return t*n; } friend ostream & operator<<(ostream &os, const Time &t); };
inline void Time::reset(int h, int m) { hours = h; mintues = m; }
#endif
#include <iostream> #include "mytime.h" using namespace std;
Time::Time() { hours = mintues = 0; cout << "调用默认构造函数" << endl; }
Time::Time(int h, int m) :hours(h), mintues(m) { cout << "调用显式构造函数" << endl; }
Time::Time(const Time &t) { hours = t.hours; mintues = t.mintues; cout << "调用拷贝构造函数" << endl; }
Time::~Time() { cout << "调用了析构函数" << endl; }
void Time::AddHour(int h) { hours += h; }
void Time::AddMin(int m) { mintues += m; hours += mintues / 60; mintues %= 60; }
Time Time::operator+(const Time &t) const { Time sum; sum.mintues = mintues + t.mintues; sum.hours = hours + t.hours + sum.mintues / 60; sum.mintues = sum.mintues % 60; return sum; }
Time Time::operator-(const Time &t) const { Time diff; int time1 = hours * 60 + mintues; int time2 = t.hours * 60 + t.mintues; diff.hours = (time1 - time2) / 60; diff.mintues = (time1 - time2) % 60; return diff; }
Time Time::operator*(double n) const { Time result; long totalMintues = n*hours * 60 + n*mintues; result.hours = totalMintues / 60; result.mintues = totalMintues % 60; return result; }
ostream & operator<<(ostream &os, const Time &t) { os << "hours:" << t.hours << " " << "mintues:" << t.mintues << " "; return os; }
#include <iostream> #include "mytime.h" using namespace std; int main() { { Time eat_breakfast(0, 45); Time eat_lunch(1, 0); Time eat_dinner(1, 30); Time swiming(0, 45); const Time study(8, 5); Time study_cut_swim = study - swiming; Time Eat_time_day = eat_breakfast + eat_dinner + eat_lunch; cout << "学习比游泳多花" << study_cut_swim << endl; cout << "每周吃饭所花费的时间为" << (7 * Eat_time_day) << endl; } system("pause"); return 0; }
|