1、引用
C++中有一種新的數據類型,對已開辟空間在取一個名字;
就是別名,不開辟新的空間,沒有空引用;
例:int &b; 錯誤,
交換兩個數字用引用實現:
常見的幾種引用形式:
(1)、對變量引用:int a = 10;
int &b = a;
(2)、對指針引用:int *p = &a;
int *&q = p;
(3)、對數組引用:int ar[3] = {1, 2, 3,};
int (&b)[3] = ar;
此外還有以下類型的引用:
(1)、常引用 const int x = 100;
int &y = x; 錯的,非常量的不能引用常量,只有自己也加上const成為常量才可以引用。
常量只能常引用;
(2)、int n = 20;
const int &m = n; 對的,常量引用非常量可以,因為你可以改變,我要求自己不能改變而已!
變量也可以常引用;
(3)、 const double d = 12.34;
const int &f = d; 對的,此時d和f由于不是同一種數據類型,所以地址不一樣,此時f引用的不是真實的d,而是對產生的臨時變量的引用(此時會把整數截取);
(4)、double d = 12.34;
int &f = d; 錯的,臨時變量一般都具備常量的性質,我們往往在類型轉換時所產生的中間臨時變量具備常量的性質;所以要加const,對常量的引用,
加上const后,常引用對常量,因為中間的臨時變量都是常量(在類型轉換時會產生中間的臨時變量);只要類型不同,就都會轉換;
2、拷貝構造函數
(1)、對象初始化對象,調用拷貝構造函數。
Test(const Test &t){}
因為拷貝構造函數也是構造函數,所以和類名相同。
const只是為了保護t不被更改;
&必須加上,因為 Test t(t1);此時相當于t1給t初始化,調用拷貝構造函數,將陷入無窮的遞歸當中,所以要使用引用;
(2)、拷貝構造函數系統會有默認的,按其成員進行拷貝!
(3)、調用拷貝構造函數的三種場合:
a、初始化對象時,Test t(t1); 和 Test t = t1;
b、形參實參傳遞時
c、返回值為對象時,會創建一個無名的臨時變量,(此時相當于對象給對象賦值),返回的是一個新的匿名對象;
3、賦值語句
賦值語句系統也有默認的,是各成員之間相互賦值。
void operator=(const Test t);
賦值語句在對象賦值時調用,可以說是對=的重載;
此時const只是為了保護不被修改,t調用拷貝構造函數(對象給對象初始化賦值),但是為了時間和空間的效率,此處用引用更好;
void operator=(const Test &t);
此時不能連等賦值,t = t1 = t2; 這個的本質就是:t.operator=(t1.operator=(t2));
所以的有返回值呀,
Test& operator=(const Test &t){ if(this != &t){ data = t.data; } return *this; }
因為不是創建臨時無名對象,所以可以引用返回;臨時的不行,返回時空間就已經析構了。
適用場合:Test t; t = t1 =t2 = t3;(對象已經初始化過了,此時就叫做賦值);
4、函數的優化調用:
#include<iostream> using namespace std; class Test{ public: Test(int d = 0) : data(d){ cout<<"Create Test Object"<<this<<endl; } Test(const Test &t){ cout<<"Copy Create Test Object"<<this<<endl; data = t.data; } Test& operator=(const Test &t){ cout<<"Assign : "<<this<<endl; if(this != &t){ data = t.data; } return *this; } ~Test(){ cout<<"Free Test Object"<<endl; } public: int GetData()const{ return data; } private: int data; }; Test fun(Test x){ int value = x.GetData(); Test tmp(value); //創建臨時tmp對象,調用構造函數 return tmp; //返回值為對象,調用拷貝構造,借助中間橋梁返回; } //立馬先析構tmp和x臨時對象,在進行賦值語句,最后析構其他對象; int main(void){ Test t1(100); //創建對象t1,調用構造函數 Test t2; //創建對象t2,調用構造函數 t2 = fun(t1); //形參,實參傳遞,調用拷貝構造 return 0; }
優化以上的代碼,使節省空間和時間:
Test fun(Test &x){ int value = x.GetData(); return Test(value); //創建臨時無名對象,編譯器直接認為:直接就是這個t2對象 } int main(void){ Test t1(100); //創建對象t1 Test t2 = fun(t1); //不用再調用賦值語句; return 0; }
效率最低-->代碼的優化。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。