先上**:
#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.傳值呼叫 該方法把引數的實際值複製給函式的形式引...