C++運算符重載學習總結


在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)任何可以用單個參數調用的構造函數都可以用作轉換構造函數,這意味着它也可以用於隱式轉換為正在構造的類。

 

綜合例子:學習測試,僅供參考!

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
 
#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
 OperatorOverloadingClass.cpp
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);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM