C 中沒有使用 引用 造成的問題

2021-09-28 14:45:51 字數 2010 閱讀 4348

先上**:

#include

using

namespace std;

#include

class

person

person add

(person &p)};

intmain()

寫這段**的目的是為了學習this指標。this指標可已返回物件本身。所以 p2.add(p1).add(p1).add(p1); 語句可以實現p2體重加上多個p1體重的效果。

但是問題來了。

執行結果如下:

這結果不對啊,怎麼就加了乙個p1?這怎麼會回事??為了查詢問題,我試著在類方法add上增加了一句來顯示執行過程的語句。

person add

(person &p)

之後執行結果如下:

???不對啊,都已經加到40了,怎麼最後又變成20了??

嗯,好像發現**不對勁了。是不是產生了匿名物件??

於是為了驗證猜想,將**小改了一下,如下:

class

person

person

(const person& p)

person add

(person &p)};

intmain()

我在類中增加了乙個屬性name,給了他乙個預設值p3,同時,重寫了拷貝建構函式,拷貝函式中只拷貝屬性weight。這樣,當add方法中的this->name列印出p3的時候就知道這是產生匿名物件了。

果然,出現了匿名物件:

這不對啊,怎麼會出現匿名物件。。。。

哦,馬虎了。類方法add的返回值沒加 & ,所以其返回值是乙個person物件。

首先,看第一部分p2.add(p1),物件p2呼叫了add方法,輸入引數為p1物件,由於是p2直接呼叫,所以該步確實修改了p2的weight屬性,變為20.

然後,在執行==p2.add(p1)==後會又乙個返回值,返回值為*this。在該步中,是p2呼叫的add方法,所以this指標是指向p2的指標,*this就是p2物件本身。當乙個方法進行值返回返回物件時,返回的並不是物件的本身,而是給物件的拷貝。想要驗證的話很簡單,在拷貝建構函式中新增乙個輸出:

person

(const person& p)

執行結果如下:

可以看到,在輸出p2的weight是:20後,呼叫了拷貝建構函式。所以其返回了乙個匿名物件,這個匿名物件是p2的拷貝。

再然後,==p2.add(p1).add(p1)在此呼叫了add方法,是p2.add(p1)的返回值呼叫了add方法,而p2.add(p1)==的返回值是乙個匿名類,所以其呼叫add方法修改的是該匿名類中的屬性,並不是p2的屬性,所以p2的weight依舊是20。

==p2.add(p1).add(p1).add(p1);與p2.add(p1).add(p1)==同理。

所以最後,p2的weight的值是20。

正確的寫法應該是:

person&

add(person &p)

執行結果如下:

add方法的返回值應該是乙個person物件那個的引用。

這樣 p2.add(p1) 返回的就是p2的乙個引用,相當於p2本身。所以p2.add(p1).add(p1) 中再次呼叫add方法的就是p2,而不是匿名類。在執行結果中同樣可以看出,因為整個執行過程中都沒有呼叫拷貝構造方法。

引用雖然是個好東西,但是也要細心啊。

C 中沒有定義類的引用。

在有時候由於類太大。須要在類在後面定義 比如 class y class x error由於c 要求不論什麼乙個變數在引用之前必須宣告。在上述定義中我們能夠調換兩者的順序來實現。可是假設形成了迴圈?class x class y error 這樣的就不能通過簡單的調換順序來通過編譯器在呼叫之前必須宣...

c中沒有傳引用,傳引用是c 的概念

c中只有傳值方式,傳位址 指標 實際上也可以理解為傳值 位址的拷貝 無傳引用 c 中有傳引用。可以理解為起別名,當然底層是指標實現的 好處是方便操作,無需解引用就可實現指標操作 下面有例子 以下cpp include void change int a int b using namespace s...

C 中的引用問題

同樣的c 中的引用也是非常容易搞混的一節內容 這裡我自己做個總結給以後不熟悉引用的那個我複習 1.指標與引用的區別 2.引用的用途 c 之所以增加引用型別,主要是把它作為函式引數,以擴充函式傳遞資料的功能。當呼叫函式時,有三種向函式傳遞引數的方式 i.傳值呼叫 該方法把引數的實際值複製給函式的形式引...