在C ++中,我們可以使運算符適用於用戶定義的類。 這意味着C ++能夠為運算符提供數據類型的特殊含義,這種能力稱為運算符重載。
例如,我們可以在像String這樣的類中重載運算符'+',這樣我們就可以通過使用+來連接兩個字符串。
其它示例中算術運算符可以重載的的類是復數,小數,大整數等。
運算符重載的語法格式:
Return_Type classname :: operator op(Argument list)
{
Function Body
}
在上面的語法中,Return_Type是要返回給另一個對象的值類型,operator op是運算符是關鍵字的函數,op是要重載的運算符。
運算符函數必須是非靜態(成員函數)或友元函數。
運算符重載可以通過三種方法完成,它們是
1) 重載一元運算符。
2) 重載二元運算符。
3) 使用友元函數重載二元運算符。
以下是定義運算符函數的一些條件/規則:
l 在非靜態函數的情況下,二元運算符應該只有一個參數,而一元不應該有一個參數。
l 在友元函數的情況下,二元運算符應該只有兩個參數,而一元應該只有一個參數。
l 如果實現了運算符重載,則所有類成員對象都應該是公共的。
運算符函數和普通函數有什么區別?
運算符函數與普通函數相同。 唯一的區別是,運算符函數的名稱始終是operator關鍵字,后跟運算符符號,並且在使用相應的運算符時調用運算符函數。
除了極個別的運算符外,大部分運算符都可以被重載。
以下是可以重載的運算符列表:
以下是不可以重載的運算符列表:
為什么(點),::,?:和sizeof不可以重載看這里解釋。
關於運算符重載的重要方面:
1)為了使操作符重載起作用,其中一個操作數必須是用戶定義的類對象。
2)賦值運算符:編譯器自動為每個類創建一個默認賦值運算符。 默認賦值運算符確實將右側的所有成員分配到左側,並且在大多數情況下都能正常工作(此行為與復制構造函數相同)。
3)轉換運算符:我們還可以編寫可用於將一種類型轉換為另一種類型的轉換運算符。重載的轉換運算符必須是成員方法。 其他運算符可以是成員方法或全局方法。
4)任何可以用單個參數調用的構造函數都可以用作轉換構造函數,這意味着它也可以用於隱式轉換為正在構造的類。
綜合例子:學習測試,僅供參考!
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 |
#ifndef
OPERATOROVERLOADINGCLASS_H #define OPERATOROVERLOADINGCLASS_H #include <iostream> using namespace std; const int SIZE = 10 ; class OperatorOverloadingClass { public : OperatorOverloadingClass(); OperatorOverloadingClass( const int &number, const float &fnumber); // 賦值運算符 void operator = ( const OperatorOverloadingClass &obj) { m_number = obj.m_number; } // 函數調用()運算符 OperatorOverloadingClass operator ()( int a, int b, int c) { OperatorOverloadingClass D; // just put random calculation D.m_number = a + b + c; return D; } void print(); /* OperatorOverloading */ // 算術運算符 // + OperatorOverloadingClass operator + ( const OperatorOverloadingClass &obj); // - OperatorOverloadingClass operator - ( const OperatorOverloadingClass &obj); // * OperatorOverloadingClass operator * ( const OperatorOverloadingClass &obj); // / OperatorOverloadingClass operator / ( const OperatorOverloadingClass &obj); // % OperatorOverloadingClass operator % ( const OperatorOverloadingClass &obj); // 關系運算符 // < bool operator < ( const OperatorOverloadingClass &obj); // > bool operator > ( const OperatorOverloadingClass &obj); // <= bool operator <= ( const OperatorOverloadingClass &obj); // >= bool operator >= ( const OperatorOverloadingClass &obj); // == bool operator == ( const OperatorOverloadingClass &obj); // != bool operator != ( const OperatorOverloadingClass &obj); // 位運算符 // ^ OperatorOverloadingClass operator ^ ( const OperatorOverloadingClass &obj); // & OperatorOverloadingClass operator & ( const OperatorOverloadingClass &obj); // | OperatorOverloadingClass operator | ( const OperatorOverloadingClass &obj); // 邏輯運算符 // && bool operator && ( const OperatorOverloadingClass &obj); // || bool operator || ( const OperatorOverloadingClass &obj); // 取地址運算符& int * operator &() { return & this ->m_number; } // 內存操作運算符* int operator *(OperatorOverloadingClass *obj) { return obj->m_number; } // 輸入輸出運算符 // << friend ostream & operator <<(ostream &output, const OperatorOverloadingClass &obj ) { output << "number : " << obj.m_number; return output; } // >> friend istream & operator >>(istream &input, OperatorOverloadingClass &obj) { input >> obj.m_number; return input; } // 自增自減運算符 // ++i OperatorOverloadingClass operator ++(); // i++ OperatorOverloadingClass operator ++( int ); // --i OperatorOverloadingClass operator --(); // i-- OperatorOverloadingClass operator --( int ); // 數組成員訪問運算符[] int & operator []( int i) { if ( i > SIZE ) { cout << "Index out of bounds" << endl; // return first element. return arr[ 0 ]; } return arr[i]; } // 類成員訪問運算符-> // https://www.cnblogs.com/codingmengmeng/p/9064702.html // 復合賦值運算符:+=、-=、*=、/=、%=、<<=、>>=、^=、&=、|= void operator += ( const OperatorOverloadingClass &obj) { m_number += obj.m_number; } // 其余類似 // 重載類型轉換 operator int () { return m_number; } operator float () { return m_fnumber; } // new delete void * operator new (size_t size); void operator delete ( void *p); void * operator new [](size_t size); void operator delete []( void *p, size_t size); private : int m_number; float m_fnumber; int arr[SIZE]; }; #endif // OPERATOROVERLOADINGCLASS_H |
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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
#include
"OperatorOverloadingClass.h"
#include <QDebug> OperatorOverloadingClass::OperatorOverloadingClass() { m_number = 0 ; m_fnumber = 0 . 0 ; for ( int i = 0 ; i < SIZE; i++) { arr[i] = i; } } OperatorOverloadingClass::OperatorOverloadingClass( const int &number, const float &fnumber) : m_number(number) , m_fnumber(fnumber) { for ( int i = 0 ; i < SIZE; i++) { arr[i] = i; } } void OperatorOverloadingClass::print() { qDebug() << "m_number =" << m_number; } OperatorOverloadingClass OperatorOverloadingClass:: operator +( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = this ->m_number + obj.m_number; return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator -( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = this ->m_number - obj.m_number; return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator *( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = this ->m_number * obj.m_number; return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator /( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = this ->m_number / obj.m_number; return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator %( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = this ->m_number % obj.m_number; return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator ^( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = ( this ->m_number) ^ (obj.m_number); return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator &( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = ( this ->m_number) & (obj.m_number); return out; } OperatorOverloadingClass OperatorOverloadingClass:: operator |( const OperatorOverloadingClass &obj) { OperatorOverloadingClass out; out.m_number = ( this ->m_number) | (obj.m_number); return out; } bool OperatorOverloadingClass:: operator &&( const OperatorOverloadingClass &obj) { return ( this ->m_number) && (obj.m_number); } bool OperatorOverloadingClass:: operator ||( const OperatorOverloadingClass &obj) { return ( this ->m_number) || (obj.m_number); } bool OperatorOverloadingClass:: operator <( const OperatorOverloadingClass &obj) { if (m_number < obj.m_number) { return true ; } return false ; } bool OperatorOverloadingClass:: operator >( const OperatorOverloadingClass &obj) { if (m_number > obj.m_number) { return true ; } return false ; } bool OperatorOverloadingClass:: operator <=( const OperatorOverloadingClass &obj) { if (m_number <= obj.m_number) { return true ; } return false ; } bool OperatorOverloadingClass:: operator >=( const OperatorOverloadingClass &obj) { if (m_number >= obj.m_number) { return true ; } return false ; } bool OperatorOverloadingClass:: operator ==( const OperatorOverloadingClass &obj) { if (m_number == obj.m_number) { return true ; } return false ; } bool OperatorOverloadingClass:: operator !=( const OperatorOverloadingClass &obj) { if (m_number != obj.m_number) { return true ; } return false ; } // overloaded prefix ++ operator OperatorOverloadingClass OperatorOverloadingClass:: operator ++ () { ++m_number; // increment this object return OperatorOverloadingClass(m_number, 0 . 0 ); } // overloaded postfix ++ operator OperatorOverloadingClass OperatorOverloadingClass:: operator ++( int ) { // save the orignal value OperatorOverloadingClass T(m_number, 0 . 0 ); // increment this object ++m_number; // return old original value return T; } // overloaded prefix -- operator OperatorOverloadingClass OperatorOverloadingClass:: operator -- () { --m_number; // increment this object return OperatorOverloadingClass(m_number, 0 . 0 ); } // overloaded postfix -- operator OperatorOverloadingClass OperatorOverloadingClass:: operator --( int ) { // save the orignal value OperatorOverloadingClass T(m_number, 0 . 0 ); // increment this object --m_number; // return old original value return T; } void *OperatorOverloadingClass:: operator new (size_t size) { return malloc(size); } void OperatorOverloadingClass:: operator delete ( void *p) { free(p); } inline void *OperatorOverloadingClass:: operator new [](size_t size) { OperatorOverloadingClass *p = (OperatorOverloadingClass *)malloc(size); return p; } inline void OperatorOverloadingClass:: operator delete []( void *p, size_t size) { free(p); } |