關於傳值傳引用,const的使用

2021-07-26 11:24:52 字數 4096 閱讀 8099

這裡主要做一些優化

拿其中的乙個函式作為例子

// 函式原型

class vector

// 函式定義

vector vector::operator+(vector v1)

在這裡,我們傳入了乙個v1物件

當我這樣子呼叫

vector v1(2,3);

vector v2(3,4);

vector v;

v =v1 + v2;

相當於這樣子

v = v1.operator+(v2);

v2作為引數傳進函式中

聰明的你們當然知道這是傳值引用

所以,v2傳入函式時會建立乙個臨時物件

然後用這個臨時物件參與運算

最後返回乙個另乙個臨時物件temp

退出函式時,v2形成的臨時物件執行析構函式被銷毀

臨時物件temp賦值給物件v後被自動銷毀

選擇:

按值傳遞,按址傳遞,按引用傳遞

按值傳遞需要建立臨時物件

需要消耗額外的計算與儲存資源

最好是傳入指標或引用

當然在c++中引用是更好的選擇

因此我們可以這樣修改

// 函式原型

class vector

// 函式定義

vector vector::operator+(vector & v1)

按值傳遞和按引用傳遞(暫時不討論指標了)

按值傳遞的最大優點是不會修改原來的資料

現在我們傳入了引用

如果操作有失誤,可能會使得源資料被修改

這時候我們可以考錄傳入const的引用

因此我們可以這樣修改

// 函式原型

class vector

// 函式定義

vector vector::operator+(const vector & v1)

這樣子傳遞引數,就能夠防止源資料被修改

(當然如果本來就要修改的話那就不要const羅)

我們回顧下vector我們定義的建構函式的原型

vector(int a, int b);

事實上

建構函式不僅僅在初始化的時候可以呼叫

它本來就可以當成乙個函式直接在類裡使用

所以 上面的例子可以進一步優化

// 函式原型

class vector

// 函式定義

vector vector::operator+(const vector & v1)

這裡建構函式vector直接根據引數生成乙個臨時物件

然後把這個臨時物件返回。

這樣子能夠使整個函式更為簡潔

可讀性也更強

剛剛講到乙個傳入引數用const

還有乙個作用

而且是乙個很重要很重要的作用

我們可以像建立常量一樣建立常量物件

vector v1(2,3);

const vector v2(3,4);

這樣子,const的使用使v2成為常量物件

那可以這樣子嗎?

vector v1(2,3);

const vector v2(3,4);

vector v;

v =v1 + v2;

這樣子的呼叫

v = v1.operator+(v2);

參照 如果這樣

vector operator+(vector & v1);

v2是個常量,但是函式引數卻不是常量引用

如果成功傳遞,將會導致原本是常量的內容被修改!

因此這樣的引數傳遞是不能過的

按值傳遞

由於改變的是臨時變數

是不是const都沒關係

按引用傳遞

由於會改變源資料

普通引用的引數只能傳入普通的變數

const&的引數

既能接受普通變數又能接受const變數

相容性++

vector v1(2,3);

const vector v2(3,4);

vector v;

這樣的宣告

我能否這樣做

v = v2 + v1;

和剛剛的例子比起來,好像只是換了下順序

但是他的函式呼叫形式變了

v = v2.operator+(v1);

好像也沒什麼問題?

注意!這裡的v2是常量物件

複習以前說過的this指標

this指標在物件中指的是

呼叫物件本身的指標

複習const成員函式

在成員函式後面加const

相當於給this指標加上了const

防止物件成員函式修改自身資料

複習完,再看看const物件

const物件

不就是自身資料不會被修改的物件嗎

它的資料只要初始化之後

就不能夠被修改

因此const物件裡的this指標

應該全都要是const * 型別的

可是這裡的運算子過載函式並不是const成員函式

裡面的this指標不是const的

所以上面的呼叫

v = v2.operator+(v1);

是行不通的

因此,只要是不需要修改自身資料

常量物件可能執行的類方法

都需要用const成員函式

修改方案如下:

// 函式原型

class vector

// 函式定義

vector vector::operator+(const vector & v1) const

如果對用乙個函式有兩個不同的版本

乙個是const成員函式

乙個不是const成員函式

那麼常量物件呼叫函式將會執行const成員函式

普通物件將會呼叫const成員函式

這也個根據this指標const屬性不同

導致函式形參列表不同特徵標不同

然後函式過載的乙個例項

引數屬性的選擇,

按值傳遞,按引用傳遞

是否使用const

盡可能地使用const,能增強類的相容性(對常量物件的相容)

const成員函式的理解(this指標的const屬性)

建構函式的使用,能夠大大降低程式的複雜度

算是出來了

我們已經詳細講解了+號的過載

以及它的優化

之後我們就可以加上

* 來用最舒服的方式

實現向量之間最基本的運算

通過過載

>, >= , < , <= ,==

可以實現向量之間的大小比較

還可以過載

+=, -=,*=

使得向量的使用更加的接近普通變數

當然,還可以根據向量的特徵

自己在定義多幾個向量的類成員函式

比如計算兩個向量之間的角度

還可以在向量類私有成員中加上長度

並在初始化時自動計算長度

從而在類內部呼叫長度的時候更為方便

傳值 傳值引用

首先對傳值和傳引用要有個基本的概念 傳值 傳遞的是值的副本。方法中對副本的修改,不會影響到呼叫方。傳引用 傳遞的是引用的副本,共用乙個記憶體,會影響到呼叫方。此時,形參和實參指向同乙個記憶體位址。對引用副本本身 物件位址 的修改,如設定為null,重新指向其他物件,不會影響到呼叫方。直接上 更好的理...

關於傳值與傳引用的討論

對於使用者自定義的型別來說,傳引用一般要比傳值高效。傳引用不需要經過物件過程,在 effective c 中作者舉了個例子 class base class derive public base 此刻我們擁有乙個派生類物件derive 對derive傳值的結果是共需要進行六次的建構函式的呼叫 物件本...

關於傳值與傳引用的討論

對於使用者自定義的型別來說,傳引用一般要比傳值高效。傳引用不需要經過物件過程,在 effective c 中作者舉了個例子 class base class derive public base 此刻我們擁有乙個派生類物件derive 對derive傳值的結果是共需要進行六次的建構函式的呼叫 物件本...