程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++學習筆記(9.操作符重載)

c++學習筆記(9.操作符重載)

編輯:C++入門知識

本節知識點:

1.c++標准庫:

a.c++標准庫並不是c++語言的一部分,c++標准庫是由c++語言編寫而成的類庫和函數的集合。c++標准庫中定義的類和對象都位於std命名空間中,c++標准庫的頭文件都不帶.h後綴,並且c++標准庫涵蓋了c庫的功能,如c庫中對應c++庫中的 b.c++標准庫預定義了多數常用的數據結構,如: c.c++標准庫中的cout和cin的使用方式(代碼如下):
#include 
#include 

using namespace std;

int main()
{
	int a;
	int b;
	printf("put a :\n");
	cin >> a;
	printf("put b :\n");
	cin >> b;
	cout << "sum is : " << a+b << endl;
	return 0;
} 

2.全局函數的操作符重載:

a.c++中可以通過operator關鍵字利用函數擴展操作符,即操作符重載,operator的本質是通過函數重載實現操作符的重載,所以操作符重載遵循函數重載的規則。 b.c++中類的友元的定義:private聲明使得類的成員不能被外界訪問,但是通過friend關鍵字可以以友元的形式開放權限。 代碼示例如下:
#include 

using namespace std;
class test
{
private:
	int a;
	int b;
public:
	test (int a, int b)
	{
		this->a = a;
		this->b = b;
	}
	int geta()
	{
		return a;
	}
	int getb()
	{
		return b;
	}
	/*注意友元可以是任何形式的函數*/ 
	friend test operator+ (test& a1, test& a2); //友元聲明 
};

test operator+ (test& a1, test& a2) //全局操作符重載函數 
{
	test c(0,0);
	c.a = a1.a + a2.a;
	c.b = a1.b + a2.b;
	return c;
}
int main()
{
	test n1(1,2);
	test n2(2,3);
	test n3(0,0);
	cout << "a is : " << n3.geta() <注意:上代碼中的 n1+n2 其實等價於  operator+(n1,n2)    

3.類的成員函數的操作符重載:

a.用成員函數重載操作符:比全局函數少一個參數,即左操作數,也是這個類的對象。同時不需要使用friend關鍵字。 代碼如下:
#include 
#include  
using namespace std;
class test
{
private:
	int a;
	int b;
public:
	test(int a, int b)
	{
		this->a = a;
		this->b = b;
	}
	test operator+ (test& n2);
	friend test operator+ (test& n1, test& n2);
	friend ostream& operator<<(ostream& out , test& n);
};
ostream& operator<<(ostream& out , test& n)
{
	out << "a is : " << n.a <注意:成員函數的操作符重載,op1 符號 op2 等價於op1.operator符號(op2)   所以說op1必須是這個類的對象
           全局函數的操作符重載,op1 符號 op2 等價於 
operator符號(op1, op2)   所以說op1和op2可以是任何類型

4.成員函數和全局函數的操作符重載適用情況:

a.如果左操作數不是一個類的對象,只能用全局函數的操作符重載 b.當無法修改左操作數的類時,使用全局函數進行重載,就像前面重載的<<符號一樣,因為不能修改ostream這個類,所以就只能使用全局函數的操作符重載 c.其實大量的成員函數的操作符重載,都可以被全局函數的操作符重載代替,但是對於=賦值操作符、[ ]數組運算操作符、()函數調用操作符、->指針操作符只能通過成員函數進行重載。(這四個操作符是c++編譯器中的特殊規定只能使用成員函數進行操作符重載,不要問為什麼,違反了編譯會出錯) d.c++編譯器會為每一個類提供一個默認的賦值操作符,默認的賦值操作符只是做簡單的值的復制。當類中存在指針成員變量(尤其是指向new出來的內存的指針)時,就需要重載賦值操作符了,否則在析構函數中delete的時候,就會對同一個地址delete兩次!!! 代碼如下:
#include 

using namespace std;

class test
{
private:
	int a;
	int b;
public:
	test(int a, int b)
	{
		this->a = a;
		this->b = b;
	}
/*	test(const test& n)
	{
		cout<<"hhhhhhh"<注意:第一,c++編譯器會為類提供一個拷貝構造函數,提供一個賦值操作符重載函數。兩個默認函數的功能相同,都是對類的成員變量進行簡單的復制。
            第二,但是兩個函數之間是相互獨立的,有各自的應用場景,如在test b = a; 類定義初始化的時候,此時調用的是類的拷貝構造函數。還有就是在函數參數為類的時候void fun(test a),在函數調用進行參數傳遞的時候,調用拷貝構造函數,實現實虛參之間的傳遞。如在b = a 兩個類直接賦值的時候,調用的是默認賦值操作符重載函數。
            第三,就是這兩個默認提供的函數,一旦用戶自己定義了,原來c++編譯器提供的默認函數就會失效。

5.++操作符的重載:

a.c++中通過一個占位參數來區分前置運算和後置運算,且++運算符的重載即可以是全局函數也可以是成員函數,代碼如下:
#include 
using namespace std;
class test
{
private:
	int a;
	int b;
public:
	test(int a, int b)
	{
		this->a = a;
		this->b = b;
	}
	friend ostream& operator<<(ostream& out , test& n);
	friend test operator++ (test& a, int);
	friend test& operator++ (test& a);
};
ostream& operator<<(ostream& out , test& n)
{
	out << "a is : " << n.a <注意: operator++ (test& a, int) 為a++ 後置運算,operator++(test& a) 為++a 前置運算

6.&&和||操作符的重載:

a.特別注意不要對&&和||操作符進行重載,因為正常的&&和||內置實現了短路規則,但是操作符重載是靠函數重載來完成的,操作數作為函數參數傳遞,c++中的函數參數都會被求值,無法實現短路規則。 代碼如下:
#include 
#include 

using namespace std;

class Test
{
    int i;
public:
    Test(int i)
    {
        this->i = i;
    }
    
    Test operator+ (const Test& obj)
    {
        Test ret(0);
        
        cout<<"Test operator+ (const Test& obj)"<注意:正常來說 上面的 t1+t2 是應該被短路的,不應該被執行的,但是由於t1+t2實質上是函數的參數,所以被執行了,違背了短路規則!!!

7.本節總結(幾個常出面試題):

a. =賦值操作符 、[]數組操作符 、()函數調用操作符 、->指針操作符,這個四個操作符只能通過成員函數進行重載 b.++操作符通過一個int參數進行前置與後置的重載 c. c++中不要重載&&和||操作符

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved