C++ 一元、二元運算符重載

運算符重載,就是對已有的運算符重新進行定義,賦予其另一種功能,使他適應不同的數據類型。

運算符重載的本質:函數重載       關鍵字:operator

一、一元運算符重載

一元運算符就是對一個數進行操作

一元運算符重載利用成員函數進行重載時,就不用給()內傳參數了,()內有隱藏的*this

負號運算符的重載

定義一個Coordinate座標類,分別通過成員函數和友元函數對負號運算符進行重載

通過成員函數對負號運算符進行重載:

#include<iostream>
using namespace std;

/******************************************
一元運算符重載
要求:
定義一個Coordinate座標類
成員函數:構造、getX、getY,數據成員:m_iX,m_iY
1、負號運算符重載(成員函數,友元函數)
2、++運算符重載(前置++,後置++)
*******************************************/

class Coordinate
{
	Coordinate(int x,int y);

        //通過成員函數對符號運算符進行重載 
	Coordinate &operator-();//讓他返回出來的是它本身,這樣才能讓他再進行負號運算符的運算,所以返回值寫成Coordinate &

	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

//成員函數實現負號運算符重載
Coordinate &Coordinate::operator-()
{
	this->m_iX = -(this->m_iX);//m_iX = -m_iX;
	this->m_iY = -(this->m_iY);

	return *this;//返回的是一個對象
}


int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;
	-coor1;//coor1.operator-();成員函數
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	return 0;
}

運行結果:

通過友元函數對負號運算符進行重載:


#include<iostream>
using namespace std;

/******************************************
一元運算符重載
要求:
定義一個Coordinate座標類
成員函數:構造、getX、getY,數據成員:m_iX,m_iY
1、負號運算符重載(成員函數,友元函數)
2、++運算符重載(前置++,後置++)
*******************************************/

class Coordinate
{
	friend Coordinate &operator-(Coordinate &c);//friend Coordinate &operator-(Coordinate c);
	//()內要傳入參數,其實就是在成員函數重載中要傳入的*this,所以應該是Coordinate的一個對象,爲了傳遞效率,也可以傳入一個對象的引用
public:
	Coordinate(int x,int y);
	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

Coordinate &operator-(Coordinate &c)//友元函數重載符號運算符
{
	c.m_iX = -c.m_iX;
	c.m_iY = -c.m_iY;

	return c;
}

int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	operator-(coor1);//-coor1;
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;

	return 0;
}

運行結果:

前置++、後置++重載

#include<iostream>
using namespace std;

Coordinate
{
public:
	Coordinate(int x,int y);
	Coordinate &operator++();//前置++的運算符重載,返回的是一個Coordinate的引用
	Coordinate operator++(int);//後置++的運算符重載,參數int只是爲了表示當前的++是後置++
//返回的是一個對象而不是引用,是因爲後置++是在下一行代碼再去訪問這個對象的時候纔會返回++之後的值,如果返回引用的話,函數結束後,引用就會被釋放
	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

Coordinate &Coordinate::operator++()//前置++
{
	++m_iX;
	++m_iY;

	return *this;
}
Coordinate Coordinate::operator++(int)//後置++
{
	Coordinate old(*this);//利用默認拷貝構造函數構造一個臨時對象old,將++之前的值存儲在臨時對象old中
	this->m_iX++;
	this->m_iY++;

	return old;//當前這個表達式是他++之前的值,下一行代碼再去訪問這個對象的時候,纔是++之後的值
}


int main()
{
	Coordinate coor1(1,3);
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;//1,3

	coor1.operator++(0);//參數0只是標識是後置++
	cout<<coor1.getX()<<","<<coor1.getY()<<endl;//2,4
	
	cout<<(coor1++).getX()<<",";//2
	cout<<(coor1++).getY()<<endl;//5

	return 0;
}

運行結果:

二、二元運算符重載

1、“+號”運算符重載(成員函數,友元函數)
2、“<<”輸出運算符重載
3、“[]索引”運算符重載

#include<iostream>
using namespace std;

/******************************************
二元運算符重載
要求:
定義一個Coordinate座標類
成員函數:構造、getX、getY,數據成員:m_iX,m_iY
1、“+號”運算符重載(成員函數,友元函數)
2、“<<”輸出運算符重載
3、“[]索引”運算符重載
*******************************************/

class Coordinate
{
	//“<<”輸出運算符重載
	friend ostream& operator<<(ostream &output,const Coordinate &c);//返回值是ostream

	//“+號”運算符通過友元函數重載
	friend Coordinate operator+(const Coordinate &c1,const Coordinate &c2);
public:
	Coordinate(int x,int y);

	//“+號”運算符通過成員函數重載,不能傳引用,要傳對象
	//Coordinate operator+(const Coordinate &c);

	//“[]索引”運算符重載
	int operator[](int index);

	int getX();
	int getY();
private:
	int m_iX;
	int m_iY;
};

Coordinate::Coordinate(int x,int y)
{
	m_iX = x;
	m_iY = y;
}
int Coordinate::getX()
{
	return m_iX;
}
int Coordinate::getY()
{
	return m_iY;
}

/*“+號”運算符通過成員函數重載
Coordinate Coordinate::operator+(const Coordinate &c)
{
	Coordinate temp(0,0);
	temp.m_iX = this->m_iX + c.m_iX;
	temp.m_iY = this->m_iY + c.m_iY;

	return temp;
}
*/

//“+號”運算符通過友元函數重載
Coordinate operator+(const Coordinate &c1,const Coordinate &c2)
{
	Coordinate temp(0,0);
	temp.m_iX = c1.m_iX + c2.m_iX;
	temp.m_iY = c1.m_iY + c2.m_iY;

	return temp;
}

//“<<”輸出運算符重載
ostream& operator<<(ostream &output,const Coordinate &c)//返回值爲ostream&,const Coordinate &c爲要進行輸出的對象
{
	output<<c.m_iX<<","<<c.m_iY<<endl;
	return output;
}

//“[]索引”運算符重載
int Coordinate::operator[](int index)
{
	if(0 == index)
	{
		return m_iX;
	}
	if(1 == index)
	{
		return m_iY;
	}
}

int main()
{
	Coordinate coor1(1,3);
	Coordinate coor2(2,4);
	Coordinate coor3(0,0);
	coor3 = operator+(coor1,coor2);
	//coor3 = coor1 + coor2;
	cout<<coor3.getX()<<","<<coor3.getY()<<endl;//3,7

	operator<<(cout,coor1);//1,3
	cout<<coor2;//2,4

	cout<<coor2[0];//2
	cout<<coor2[1];//4

	return 0;
}

運行結果:

注:

  1. “<<”輸出運算符重載不能用成員函數進行重載,只能用友元函數進行重載;因爲在成員函數中重載第一個參數爲隱藏的*this,而“<<”輸出運算符重載第一個參數爲ostream &output
  2. “[]索引”運算符重載不能用友元函數進行重載,只能用成員函數進行重載;因爲“[]索引”運算符重載第一個參數必須爲*this,通過*this才能訪問到該對象的數據
  3. 賦值運算符重載函數不能被繼承

    因爲相較於基類,派生類往往要添加一些自己的數據成員和成員函數,如果允許派生類繼承基類的賦值運算符重載函數,那麼,在派生類不提供自己的賦值運算符重載函數時,就只能調用基類的,但基類版本只能處理基類的數據成員,在這種情況下,派生類自己的數據成員怎麼辦?                        所以,C++規定,賦值運算符重載函數不能被繼承。

  4. 賦值運算符重載函數只能是類的非靜態的成員函數,不能是靜態成員函數,也不能是友元函數

     

    其實,之所以不是靜態成員函數,是因爲靜態成員函數只能操作類的靜態成員,不能操作非靜態成員。如果我們將賦值運算符重載函數定義爲靜態成員函數,那麼,該函數將無法操作類的非靜態成員,這顯然是不可行的。

     

三、可重載運算符/不可重載運算符

下面是可重載的運算符列表:

雙目算術運算符 + (加),-(減),*(乘),/(除),% (取模)
關係運算符 ==(等於),!= (不等於),< (小於),> (大於>,<=(小於等於),>=(大於等於)
邏輯運算符 ||(邏輯或),&&(邏輯與),!(邏輯非)
單目運算符 + (正),-(負),*(指針),&(取地址)
自增自減運算符 ++(自增),--(自減)
位運算符 | (按位或),& (按位與),~(按位取反),^(按位異或),,<< (左移),>>(右移)
賦值運算符 =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空間申請與釋放 new, delete, new[ ] , delete[]
其他運算符 ()(函數調用),->(成員訪問),,(逗號),[](下標)

下面是不可重載的運算符列表:

  • .:成員訪問運算符
  • .*, ->*:成員指針訪問運算符
  • :::域運算符
  • sizeof:長度運算符
  • ?::條件運算符
  • #: 預處理符號

還可參考:一文說盡C++賦值運算符重載函數(operator=) 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章