Re: [問題] class的assignment運算子 (C++ Primer …

看板C_and_CPP (C/C++)作者 (☆㊣↖煞氣ㄟ阿喂↘ξ★)時間15年前 (2010/11/23 20:29), 編輯推噓1(103)
留言4則, 2人參與, 最新討論串2/4 (看更多)
我整理一下大家幫我回答的結論: 1. HasPtr Obj2 = Obj1; 是拿Obj1初始化Obj2,所以呼叫copy ctor,等價於 HasPtr Obj2(Obj1); 不過這邊我還是有個小疑問,compiler怎會知道拿copy ctor幫Obj2作做初始化呢? 為什麼Obj2不是先隱喻地呼叫一個沒有參數的ctor(假設有寫)做初始化(initialization) ,然後再用operator= 給Obj2賦值(assignment)呢? 如果用 HasPtr Obj2(Obj1); 那沒問題就是一定呼叫copy ctor。 2. operator= 適用時機: 當物件已經存在,但被賦值的時候: HasPtr Obt2; ////以沒有參數的ctor進行初始化 //// Obj2 = Obj1; //// 賦值 //// 這時候會呼叫覆寫後的operator=。 以上有錯請指正囉!! ※ 引述《kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)》之銘言: 我翻到C++ primer 4ed p501時,書上說class內有pointer最好要寫copy ctor 跟 assignment 運算子,但是我看到p501有一種解法是value-like class 的作法, 意即class內有pointer,且當class有copy行為或assign行為時, class會另創一個空間給他的pointer指。 不過我覺得它p501的 operator= 覆寫很怪,節錄如下: class HasPtr{ public: HasPtr(const int& p, int i):ptr(new int(p)),val(i){} // ctor HasPtr(const HasPtr& orig):ptr(new int(*orig.ptr)), val(orig.val){} HasPtr& operator=(const HasPtr&); //// 以下略 //// private: int * ptr; int val; } HasPtr& HasPtr::operator=(const HasPtr& rhs) { *ptr = *rhs.ptr; //// 這行很怪 /// 我覺得應該是下面這樣才對: /// /* delete ptr; ptr = new int(*rhs.ptr); */ val = rhs.val; return *this; } 這樣子在main裡面寫: int* p1 = new int(3); HasPtr Obj1(p1,10); HasPtr Obj2 = Obj1; ////........///// 我的改寫才正確吧? 不然Obj2出生時它的ptr還沒有跟系統要到記憶體位址, 就直接assign Obj1給它當作初始化,感覺很奇怪。 不過我實際開VS 2008去測,書上寫的也確實沒問題, 只是當我執行 HasPtr Obj2 = Obj1; 這行時, 我覆寫的operartor= 這個函式完全沒有執行到,不過Obj2卻初始化成跟Obj1一樣。 怎麼會這樣子呢? 還請各位高手指導一下,謝謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.144.17 ※ 編輯: kkroy 來自: 140.113.144.17 (11/23 19:55) ※ 編輯: kkroy 來自: 140.113.144.17 (11/23 19:56)

11/23 20:00,
1. ptr 在 ctor 不就要空間了? 2. Compiler幫你最佳化了XD
11/23 20:00

11/23 20:03,
因為HasPtr Obj2 = Obj1; 呼叫的是 copy ctor, 不是=
11/23 20:03

11/23 20:04,
推樓上
11/23 20:04

11/23 20:05,
對! 我發現式呼叫copy ctor了....但是為什麼呢?
11/23 20:05

11/23 20:05,
用=的話,會執行參數型態跟Obj1相同的ctor
11/23 20:05

11/23 20:05,
我以為是呼叫operator=
11/23 20:05

11/23 20:07,
=是用在賦值,你把賦值跟初始搞混了
11/23 20:07

11/23 20:08,
如果改成HasPtr Obj2; Obj2=Obj1; 結果就是你要的
11/23 20:08

11/23 20:09,
不過你要再加一個HasPtr()就是了
11/23 20:09

11/23 20:13,
噢噢 我瞭解了 所以HasPtr Obj2 = Obj1為初始化
11/23 20:13

11/23 20:13,
等意於 HasPtr Obj2(Obj1),所以都是呼叫copy ctor
11/23 20:13
-- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.144.17

11/23 20:37, , 1F
1.編譯器會找任何一個可以從等號右邊的引數產生HasPtr
11/23 20:37, 1F

11/23 20:38, , 2F
物件的建構子或轉型運算子, 找不到才使用trival ctor
11/23 20:38, 2F

11/23 20:39, , 3F
用 =初始化時不會呼叫 default ctor, 因為語意不同
11/23 20:39, 3F

11/23 20:42, , 4F
受教了! 太感謝你!
11/23 20:42, 4F
文章代碼(AID): #1CwxEzvW (C_and_CPP)
文章代碼(AID): #1CwxEzvW (C_and_CPP)