[英]Dereference and return by reference
考慮一個小單元測試用例
struct A
{
virtual void func(){}
A& foo()
{
A *obj = reinterpret_cast<A*>(0xdeadbeef);
return *obj; //1
}
};
int main()
{
A obj = obj.foo();
}
在第1
行是實現定義/未指定,因為我們通過引用返回,所以不會發生deference,如果沒有對指向的對象進行顯式訪問,程序不會崩潰?
我與我的一位同事爭論過,他提到在大多數情況下,編譯器會優化obj
的解引用,因為我們通過引用返回它並且這段代碼不會崩潰?
謝謝
我在MS VC8.0中反匯編代碼,發現更有趣的東西:
006D48D6 mov dword ptr [ebp-8],ecx
A *obj = reinterpret_cast<A*>(0xdeadbeef);
006D48D9 mov dword ptr [obj],0DEADBEEFh
return *obj; //1
006D48E0 mov eax,dword ptr [obj] //2
}
006D48E3 mov esp,ebp
006D48E5 pop ebp
006D48E6 ret
// 2表示只將obj的地址作為返回值放入eax寄存器。
006D39FC lea ecx,[ebp-190h]
006D3A02 call A::foo (6A8C12h)
006D3A07 push eax //3
006D3A08 lea ecx,[ebp-190h]
006D3A0E call A::A (6B89BEh)
eax是0xdeadbeef,並且作為臨時局部變量推送到堆棧。 比我們調用復制構造函數(這是微不足道的)。 所有這些操作都只是傳遞地址(這是非法的,但程序不關心)。因為A結構沒有綁定到特定對象的任何成員,並且程序不會嘗試通過取消引用找到特定對象,如果它沒有因為這枚炸彈沒有被解雇。
A *obj = reinterpret_cast<A*>(0xdeadbeef);
A tmp ;
temp = *obj;
即使這樣也可以,因為operator =也通過引用傳遞,實際上傳遞了地址。如果添加成員變量,它將失敗,因為它將嘗試查找並復制成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.