不好馴服的析構函式
本文假定您對
很願意和您交朋友:
注:想問我是學c
還是c++
的朋友就不要發郵件了,謝謝!
首先看乙個深拷貝的例子
可能我寫的有點亂
,成員變數包括乙個指標,其實是乙個陣列,想要深拷貝。
所以我們需要過載拷貝建構函式。
初學c++
的時候,直接記住了引數是引用型別,當時對語言沒有深入的理解(雖然現在也不深入),也就沒有往心裡去,這些天模擬
stl,遇到了好多關於深拷貝的問題,而且這問題出的很怪異(我會在下午提出),因此想到了拷貝建構函式,所以在這裡需要深究一下。
拷貝建構函式的引數是引用型別。
我們可以試想一下不是引用的情況,也就是說,拷貝建構函式是下邊這個樣子:
引數傳遞的是乙個物件,按值傳遞,那麼這個物件就會被複製到right
,複製的時候又會呼叫拷貝建構函式,那又會複製乙個物件到第二次呼叫的這個拷貝建構函式裡邊,因此又需要第三次呼叫拷貝建構函式。。。想一下,是不是無限迴圈?
簡單地說:
傳值需要呼叫拷貝建構函式,而不是引用型別的拷貝建構函式又需要呼叫拷貝建構函式。因此無限迴圈。
ok,把引用的這個問題說明白,下邊說一下我這幾天遇到的這個問題:
請先看一段**:
可以試著執行一下,在我電腦上邊出現了下邊這個錯誤
很恐怖的錯誤。呵呵,讓我們詳細分析一下。
第一次a.show()
成功,說明物件
a建立沒有問題
;b.show()
失敗,說明沒有複製成功
;第二次
a.show()
失敗,說明
a被修改了,可以猜想一下,是不是被呼叫了析構函式?
現在過載 =
的時候是按值傳遞,那麼,我們傳進去的是位址p和
size。
之後是執行拷貝的函式,這個沒啥問題,把right
中的相關資料拷貝。
然後就開始執行析構函式了,首先析構的是傳進來的引數,也就是right
,由於right的p
和主函式中a的
p相等,因此
right的p
被delete
了也就是a的
p被delete
了,在這裡,我們把主函式中的a
不小心析構了一點點(把p給
delete
了)。因為函式的返回的是值,所以第二步析構的是(*this)
,這樣,就把複製後的p給
delete
了。到這裡,我們悲劇地把記憶體中所有的p
都delete了。
所以,當再次輸出a和b
的時候,全都是隨機值。
細心的朋友可能會發現,當第二次輸出a和b
的時候仍然是輸出了
10個,也就是開始的
size值。a
的size是10
不難理解。由於析構函式是在函式返回後呼叫的,所以返回的b的
size
是不改變的(
返回是在改變以前)。
我們試著改一下:
下邊是我在引數上邊加了&
,這樣,
當再次輸出a
的時候沒有錯誤
下邊是在引數right
和返回值都加了&,
這樣就沒有錯誤了。
正好符合我們的分析。
不好馴服的析構函式
首先看乙個深拷貝的例子 view plaincopy to clipboardprint?01.include 02.using namespace std 03.const int size 9 04.const int default num 6 05.class a 06.20.21.a a ...
C 析構函式 虛析構函式
1.為什麼要定義虛析構函式?如果有乙個帶有虛函式功能的類,則它需要乙個虛析構函式,原因如下 1 如果乙個類有虛函式功能,它經常作為乙個基類使用 2 如果它是乙個基類,它的派生類經常使用new來分配 3 如果乙個派生類物件使用new來分配,並且通過乙個指向它的基類的指標來控制,那麼它經常通過乙個指向它...
建構函式 析構函式 虛析構函式
說析構函式之前,先說下建構函式。建構函式用來完成對物件的一系列初始化操作,主要作用有 1.給建立的物件建立乙個識別符號 2.為物件資料成員開闢記憶體空間 3.完成物件資料成員的初始化 當並未顯示的定義建構函式時,會生成乙個預設的建構函式,預設建構函式不能完成物件資料成員的初始化,只能給物件建立一識別...