作者ric2k1 (Ric)
看板EE_DSnP
標題Re: [情報] Functional Object (for HW1.2.p3b)
時間Fri Sep 30 23:55:32 2011
: 推 gamerred:想問A a = A(10);的constructor呼叫是不是建立兩個物件 09/30 18:36
: → gamerred:再用memberwise assignment? 我的理解中implicit建構似乎 09/30 18:37
: → gamerred:與用explicit呼叫效果只有微妙的差異 而不是在上面那種說 09/30 18:38
: → gamerred:法 是這樣嗎? 09/30 18:38
這個有可能會 compiler dependent, 但就我的理解來說,
假設有 A(),
A(int),
A(const A&) // copy constructor
三種 constructors,
1. A a = A(10);
會直接 explicitly 呼叫 A(int) 來 construct a
其效果跟 "A a(10)" 是一樣的
2. A a = 10;
會直接 implicitly 呼叫 A(int) 來 construct a
其效果跟 "A a(10)" 是一樣的
3. A a = a2; // a2 is a class A object
會呼叫 copy constructor 來 construct a
其效果跟 "A a(a2)" 是一樣的
4. A a; // 先呼叫 A()
a = a2; // 再執行 '=' (assignment) operator
: 推 djshen:所以constructor會回傳一個object沒錯吧? 以前計程一直強調 09/30 19:05
: → djshen:寫constructor不可以寫回傳型態 所以沒思考到這點 09/30 19:05
嚴格來說,constructor 並不用回傳 (return) 任何東西,
他只是建立一個物件。
(底下 FYI only...)
而且 compiler 會將一些看似會產生 internal objects 的地方合併,
直接作用在同一個記憶體位置。
例如:
A operator + (const A& b) const { A sum = *this; ...; return sum; }
^ ^ ^
|---------------------------------| |
| |
這兩個 A 物件會 associate 在一起,所以這裡 ------------------|
不會有 copy constructor 被呼叫。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.36.57.234
※ 編輯: ric2k1 來自: 114.36.57.234 (09/30 23:57)
1F:→ ric2k1:忘記講 implicit constructor,補充一下... 09/30 23:58
2F:推 gamerred:謝謝老師的回答 我還有一個問題 關於最後一點 10/01 00:07
3F:→ gamerred:return by value 的時候,還是會有臨時物件出現吧? 10/01 00:08
4F:→ gamerred:以文中的例子來看 回傳的時候scope的問題還是存在 10/01 00:08
5F:→ gamerred:按照老師所說 compiler是怎麼做到優化的呢? 10/01 00:09
6F:→ ric2k1:這個我剛剛有做實驗確認過,的確沒有臨時的物件被產生出來 10/01 00:17
7F:推 djshen:推 我剛剛用typeid去看 class叫A object傳回1A A()則是 10/01 00:17
8F:→ ric2k1:我想 compiler 可以察覺到 A sum 最後都是會被備份出去, 10/01 00:18
9F:→ djshen:F1Ave 1是class name的長度 不過F ve就不懂了 10/01 00:18
10F:→ ric2k1:所以就共用一份記憶體空間 (物件) 就好了 10/01 00:18
11F:推 djshen:然後我又試了typeid((A())).name() 結果又變成1A了.. 10/01 00:42
12F:→ djshen:typeid(A()).name()是F1Ave 多個括弧有差@@ 10/01 00:43
13F:推 gamerred:我用visual studio測試的結果還是有臨時物件耶 10/01 00:49
14F:→ gamerred:我記得學計程的時候林宗男教授也強調過這一點XD 10/01 00:50
15F:→ gamerred:不過如果說某個optimization mode會幫忙弄掉我也不意外啦 10/01 00:51
16F:推 djshen:我試著cout<<&(A()); g++表示taking address of temporary 10/01 01:05
17F:→ djshen:好像跟你們說的東西不一樣 不要理我XD 10/01 01:06
18F:推 gamerred:喔 對阿 A()回傳的是一個暫時物件阿 10/01 01:11
19F:→ gamerred:阿 應該說產生... 10/01 01:11
20F:→ ric2k1:樓上說的不衝突啊! 你例子中的 A() 由於沒有人 take 就要被 10/01 01:12
21F:→ ric2k1:&() 並且 cout 出去,所以一定會產生暫時的物件,沒有辦法 10/01 01:13
22F:→ ric2k1:被其他的物件河蟹 (誤) 掉... 10/01 01:13
23F:→ ric2k1:我是指 djshen... 10/01 01:14
24F:→ ric2k1:再舉一個會被河蟹掉的例子: 10/01 01:15
25F:→ ric2k1:A a = A(30) + A(40); 10/01 01:15
26F:→ ric2k1:那個 A(30) + A(40) 的結果就不會產生臨時的物件, 10/01 01:16
27F:→ ric2k1:他們加完的結果會被直接 construct 成 a 10/01 01:17
28F:→ ric2k1:比較精確的說法應該是: 因為被河蟹掉了,所以自始至終都是 10/01 01:20
29F:→ ric2k1:在同一個記憶體位置操作 10/01 01:20
30F:→ ric2k1:// 我覺得大家可能會覺得看這個討論串有點不知所云吧 orz 10/01 01:21
31F:→ ric2k1:忍不住再說一個: 10/01 01:21
32F:→ ric2k1:a = A(30) + A(40) 就會有臨時的物件產生了... 10/01 01:22
33F:→ ric2k1:而這個臨時的物件在被 assign 給 a 之後就會被 destruct 掉 10/01 01:23
34F:推 djshen:如果照上面的operator+ 不會回傳sum嗎? 10/01 01:25
35F:推 gamerred:回樓上 如果operator+是return by value他會回傳一個 10/01 01:28
36F:→ gamerred:臨時物件 如果前面是一個新的A 就會綁上去 如果是一個舊 10/01 01:29
37F:→ gamerred:的A 就會assign完之後自我毀滅 大概就是這個意思吧 10/01 01:30
38F:推 djshen:我想也是 10/01 01:33
39F:推 djshen:實驗了一下 A a =A(30)+A(40) 好像沒有呼叫constructor耶 10/01 02:04
40F:→ djshen:operator+完之後 &a就變成&sum了 10/01 02:05
41F:→ ric2k1:overload 一下 copy constructor, 你就會看到了! 10/01 02:06
42F:推 gamerred:恩 綁好了之後其實就是原本那個阿 10/01 02:06
43F:推 djshen:我有寫copy constructor@@ 10/01 02:07
44F:→ djshen:還是說complie的時候就會把a sum變成同一個? 10/01 02:09
45F:推 gamerred:應該是如此 10/01 02:16
46F:→ ric2k1:你的 operator + 是 return A 嗎? 如果是的話,應該是會 10/01 02:17
47F:→ ric2k1:呼叫 copy constructor 來建立 a 啊! 10/01 02:17
48F:→ ric2k1:啊! 我想起來了,的確不會, 10/01 02:18
49F:→ ric2k1:A a 與 sum 綁在一起,所以只看的到 A sum 的 constructor 10/01 02:19
50F:→ ric2k1:不要理會我的自言自語... 10/01 02:19