引用容易犯的錯誤。

2021-05-23 11:00:38 字數 1191 閱讀 1339

由於物件a是個區域性物件,因此當函式物件func結束後,區域性物件a也就被刪除了。由於物件a消失了,所以func()函式返回的其實是乙個並不存在的物件的別名。

用這個不存在的物件來呼叫該物件的函式get()。該函式會返回乙個並不存在的物件的x成員。因此輸出乙個隨機數。

如果這樣,那輸出就是23,為什麼?

因為去掉引用符號後,返回方式變成了按值返回,而按值返回又會呼叫複製建構函式,複製乙個物件a的副本,然後將這個副本再賦給r,r就是這個物件a的副本的別名。

下面舉個例子說明這個:

vc6.0下輸出結果:

跳轉到func函式中!

呼叫建構函式建立乙個物件

物件a的位址0012ff00

執行複製建構函式建立乙個物件

執行析構函式

執行析構函式!

看到這個結果相信會明白不少東西。但是與此同時,這裡有個問題:

為什麼物件a的副本的生命會一直持續到main函式結束呢?(上面最後一句輸出:執行析構函式!就是物件a的副本的析構,所以有必要懷疑一下他的生命週期!)

這是因為對於引用而言,如果引用的是乙個臨時變數,那麼這個臨時變數的生存期會不少於這個引用的生存期。

(參見c++標準[class.temporary])

也就是說,直到main函式結束時,引用r的生存期結束,r所引用的臨時變數的生存期才結束,由於r所引用的是乙個物件,因此這時才會呼叫它的析構函式來釋放記憶體。

ps;順便說一下,指標是沒有這個特性的,假如將物件a的副本的位址賦給乙個指標,那麼在func函式返回物件a的副本的時候,就可以析構這個物件a的副本。

輸出結果如下:

跳轉到func函式中!

呼叫建構函式建立乙個物件

物件a的位址0012ff0c

執行複製建構函式建立乙個物件

執行析構函式

執行析構函式

分析:連續執行了兩次析構函式,將物件a和他的副本所占用的記憶體全部釋放掉了。

但是我們確實看到了get函式輸出了物件a的副本的x成員為23

於此我們也知道物件a的副本已經被刪除了啊,已經析構過了啊。為什麼這裡又輸出了他的成員x的值呢?

::這是因為析構函式呼叫並析構某個物件後,只是告訴編譯器這一塊記憶體不再為某個物件獨佔了,你可以訪問它,別的物件或者變數也可以訪問它並使用該記憶體區域儲存他們的資料,但是在他們使用之前,存放在該記憶體區域中的資料並沒有刪除,因此使用指標來訪問該區域仍然能夠得到未被修改的x的值。

指標經常容易犯的錯誤

以下內容摘自林銳博士的 高質量的c c 程式設計 雖然網上對這本書 文章?的評價不高,但是個人覺得,記憶體管理這章還是有些地方可以借鑑的。因此,摘錄這些內容算是乙個複習和總結吧!1指標與陣列的對比 1.1修改內容 char a hello a 0 x ok char p hello p 0 x er...

python中容易犯的錯誤

python寫 時,在條件語句中老是忘記加判斷導致出錯。1 對於鍊錶 樹的資料結構,當node不為none,假如要訪問node.next.next時,經常就直接寫node.next.next 或node.left.left 導致程式經常報錯 nonetype object has no attrib...

!!!!新手最容易犯的錯誤

今天寫了乙個很簡單的程式,輸入三個不同長度的字串,然後將其右對齊顯示 因為剛學了幾天,經常會犯一些錯誤,如下 file day01.py line 62 print maxn len b b syntaerror invalid syntax 以上是之前的錯誤,找了好半天,也一直沒有發現,從頭到尾推...