C++基礎 學習筆記五:多載之運算子多載
什么是運算子多載
用同一個運算子完成不同的功能即同一個運算子可以有不同的功能的方法叫做運算子多載,運算子多載是靜態多型性的體現,
運算子多載的規則
-
多載公式
回傳值型別 operator 運算子名稱 (形參表列){}
-
能夠多載的運算子
+-*/%^&|~!=<>+=-=*=/=%=^=&=|=<<>><<=>>===!=<=>=&&||++--,->*->()[]newnew[]deletedelete[] -
不能多載的運算子
sizeof、: ?、.、:: -
多載不能改變運算子的優先級和結合性
-
多載不會改變運算子的用法
-
運算子多載函式不能有默認的引數
-
多載后的運算子必須至少有一個運算元是用戶自定義的型別,以此來防止為標準型別多載運算子,
-
特殊的運算子
->、[ ]、( )、=只能以成員函式的形式多載
運算子多載的實作原理
以運算子作為名稱的函式稱之為運算子函式,這種多載稱為運算子多載,
具體實作(以運算子+ -為例)
1. 在全域范圍內多載運算子
Complex operator+(const Complex &leftArg, const Complex &rightArg)
{
return Complex(leftArg.real+rightArg.real,leftArg.imag+rightArg.imag);
}
Complex sum = leftArg + rightArg;
第五行呼叫函式operator+,并且將leftArg、leftArg作為符號函式的引數,回傳值賦值給sum,等同于sum = operator+(leftArg,rightArg);,
2.在類中多載運算子
class Complex
{
public:
Complex operator-(const Complex & arg)
{
return Complex(this.real - arg.real, this.imag - arg.imag);
}
};
Complex diff = leftArg - rightArg;
第九行呼叫函式operator-,并且將leftArg作為符號函式的引數,回傳值賦值給diff,等同于diff = leftArg.operator-(rightArg);,
運算子多載的使用例子
#include<iostream>
#include<string>
using namespace std;
enum complePart
{
real = 0,
imag
};
class Complex
{
public:
int real;
int imag;
public:
Complex() : real(0),imag(0){}
Complex(int r, int i) : real(r),imag(i){}
Complex operator-(const Complex & arg)// +,-,*,/ 這四個運算子多載方法一樣
{
return Complex(this->real - arg.real, imag - arg.imag);
}
friend Complex operator*(const Complex &leftArg, const Complex &rightArg);//友元函式
bool operator==(const Complex &arg)// ==,!= 這兩個個運算子多載方法一樣
{
if(this->real == arg.real && this->imag == arg.imag)
return true;
else
return false;
}
Complex& operator+=(const Complex &arg)// +=,-=,*=,/= 這四個運算子多載方法一樣
{
this->real += arg.real;
this->imag += arg.imag;
return *this;
}
friend istream& operator>>(istream &input, Complex &complex);
friend ostream& operator<<(ostream &output, Complex &complex);
Complex& operator++()// ++i,--i 這兩個個運算子多載方法一樣
{
++this->real;
++this->imag;
return *this;
}
Complex operator++(int i)// i++,i-- 這兩個個運算子多載方法一樣
{
Complex tempComplex = *this;
++this->real;
++this->imag;
return tempComplex;
}
void* operator new(size_t size)
{
cout << "call function void* operator new(size_t size)" << endl;
void* pointer = malloc(size);
return pointer;
}
void operator delete(void* pointer)
{
cout << "call function void operator delete(void* pointer)" << endl;
free(pointer);
}
void* operator new[](size_t size)
{
cout << "call function void* operator new[](size_t size)" << endl;
void* pointer = malloc(size);
return pointer;
}
void operator delete[](void* pointer)
{
cout << "call function void operator delete[](void* pointer)" << endl;
free(pointer);
}
void* operator new(size_t size,Complex* complex,int step)//placement new
{
cout << "call function void* operator new(size_t size,Complex* complex,int step)" << endl;
return complex + step;
}
operator int()
{
return this->real;
}//c->operator int()
int& operator [](int i)
{
int errorValue = https://www.cnblogs.com/realZhaZhaHui/p/0;
if(i == 0)
return this->real;
else//為了演示不要在意
return this->imag;
}
const int& operator[](int i) const
{
cout << "call function const int& operator[](int i) const" << endl;
if(i == 0)
return this->real;
else//為了演示不要在意
return this->imag;
}
};
Complex operator+(const Complex &leftArg, const Complex &rightArg)//全域多載
{
return Complex(leftArg.real+rightArg.real,leftArg.imag+rightArg.imag);
}
istream& operator>>(istream &input, Complex &complex)
{
input >> complex.real >> complex.imag;
return input;
}
ostream& operator<<(ostream &output, Complex &complex)
{
output << complex.real << " " << complex.imag << " ";
return output;
}
Complex operator*(const Complex &leftArg, const Complex &rightArg)
{
return Complex((leftArg.real * rightArg.real) - (leftArg.imag * rightArg.imag),
(leftArg.imag * rightArg.real) - (leftArg.real * rightArg.imag));
}
int main()
{
Complex leftArg(2,2);
Complex rightArg;
cin >> rightArg;//輸入3,3
Complex result = leftArg + rightArg;
cout << result << endl;
result = leftArg - rightArg;
cout << result << endl;
result = leftArg * rightArg;
cout << result << endl;
string str = (leftArg == rightArg)?"true":"false";
cout << str << endl;
result += leftArg;
cout << result << endl;
cout << ++result << endl;
Complex resulttttt = result++;
cout << resulttttt << endl;
cout << result << endl;
Complex* pointer = new Complex(1,1);
cout << *pointer << endl;
delete pointer;
Complex* pointerArray = new Complex[10];
cout << pointerArray[2] << endl;
new(pointerArray, 2)Complex(123,321);//placement new
cout << pointerArray[2] << endl;
cout << (int)pointerArray[2] << endl;
cout << pointerArray[2][complePart::real] << endl;
cout << pointerArray[2][complePart::imag] << endl;
delete[] pointerArray;
const Complex c_result(111,222);
cout << c_result[complePart::imag] << endl;
return 0;
}
/* 運行結果為:
3 3
5 5
-1 -1
0 0
false
2 2
3 3
3 3
4 4
call function void* operator new(size_t size)
1 1
call function void operator delete(void* pointer)
call function void* operator new[](size_t size)
0 0
call function void* operator new(size_t size,Complex* complex,int step)
123 321
123
123
321
call function void operator delete[](void* pointer)
call function const int& operator[](int i) const
222
--------------------------------
Process exited after 3.063 seconds with return value 0
請按任意鍵繼續. . .
*/
代碼分析
1.雙目運算子
+、-、*、/、%這五個運算子均為雙目運算子,多載方法相同,多載例子詳見第20、24、102、116行,其中第102行的+多載函式為全域多載,測驗詳見第127、129、131行,
2.關系運算子
==、!=、<、> 、<=、>=這六個運算子均為關系運算子,多載方法相同,多載例子詳見第25行,測驗詳見第133行,
3.自增自減運算子
++、--這兩個運算子均為自增自減運算子,由于運算子的特殊性,運算子又分為前置和后置形式,多載方法兩種形式不同,但是相同形式的多載方法相同,多載例子詳見第40、46行,測驗詳見第137、138行,
4.空間申請與釋放運算子
new、delete、new[]、delete[]這四個運算子均為空間申請與釋放運算子,多載方法相似,多載例子詳見第53、59、64、70行,測驗詳見第141、143、144、151行,在多載空間申請運算子時除new、new[]這兩種方式外還有一種方式叫做placement new,多載例子詳見第75行,測驗詳見第146行,
placement new
通常new操作分兩步:
- 分配記憶體,
- 若為類則呼叫類的建構式創建物件,
但是若已分配好記憶體如:Complex* pointerArray = new Complex[10];,若要在pointerArray[2]分配的記憶體上創建物件則需要用placement new來完成該操作,操作如下:new(pointerArray, 2)Complex(123,321);,完成該操作后pointerArray[2]中的復數物件將會變為123+321i,
5.輸入和輸出運算子
>>、<<這兩個運算子均為輸入和輸出運算子,多載方法相似,可以將輸出運算子<<和輸入運算子>>看作是C++對左移運算子<<和右移運算子>>分別進行了多載,但只能輸出輸入標準型別,多載例子詳見第38、39行,測驗詳見第126、128行,
6.其它運算子
-
(資料型別)運算子(資料型別)是強制型別轉換運算子,可以將物件轉換為相應的型別, -
[]運算子[]是下標運算子,可以將物件轉換為類似陣列,可以通過下標操縱物件,
多載運算子的形式
1.以成員函式多載運算子
成員函式多載只允許右引數的隱式轉換,一般單目運算子以成員函式多載,只能多載為成員函式的運算子:=、()、[]、->等,
2.以全域函式(友元函式)多載運算子
友元函式多載能夠接受左引數和右引數的隱式轉換,友員函式多載運算子常用于運算子的左右運算元型別不同的情況,一般雙目運算子以友元函式多載,只能多載為友元函式的運算子:<<、>>等,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/36259.html
標籤:C++
下一篇:2020年04月19日個人賽
