作者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