讀書筆記: Inside the C++ Object Model (3)
March 3rd, 2011
底下的實驗證明若 class 宣告或繼承 virtual function 時,編譯器會自動生成 constructor
exp_def_ctor.h
class CWidget
{
public:
virtual void flip() const = 0;
};
class CBell : public CWidget
{
public:
virtual void flip() const;
};
class CWhistle : public CWidget
{
public:
virtual void flip() const;
};
#include "exp_def_ctor.h"
#include
using namespace std;
void CBell::flip() const { cout << "bell" << endl; }
void CWhistle::flip() const { cout << "whistle" << endl; }
void flip(const CWidget& widget)
{
widget.flip();
}
void main()
{
CBell b;
CWhistle w;
flip(b);
flip(w);
}
CC = cl
CFLAGS = /EHsc /Zi /Fd /c
LD = link
LDARGS = /INCREMENTAL:NO /DEBUG
RM = del /q
.cpp.obj::
$(CC) $(CFLAGS) $<
test1.exe: exp_def_ctor.obj
$(LD) exp_def_ctor.obj $(LDARGS) /OUT:test1.exe /PDB:test1.pdb
clean:
$(RM) *.exe *.obj *.pdb *.idb *.ilk *.bak
all: test1.exe
windbg results
0:000> ln test1!main
d:\home\desktop\research\exp_def_ctor.cpp(13)
(01361080) test1!main | (013610c0) test1!std::endl
Exact matches:
test1!main (void)
0:000> u 01361080 013610c0
test1!main [d:\home\desktop\research\exp_def_ctor.cpp @ 13]:
01361080 55 push ebp
01361081 8bec mov ebp,esp
01361083 83ec08 sub esp,8
01361086 8d4df8 lea ecx,[ebp-8]
01361089 e852000000 call test1!CBell::CBell (013610e0)
0136108e 8d4dfc lea ecx,[ebp-4]
01361091 e86a000000 call test1!CWhistle::CWhistle (01361100)
01361096 8d45f8 lea eax,[ebp-8]
01361099 50 push eax
0136109a e8c1ffffff call test1!flip (01361060)
0136109f 83c404 add esp,4
013610a2 8d4dfc lea ecx,[ebp-4]
013610a5 51 push ecx
013610a6 e8b5ffffff call test1!flip (01361060)
013610ab 83c404 add esp,4
013610ae 33c0 xor eax,eax
013610b0 8be5 mov esp,ebp
013610b2 5d pop ebp
013610b3 c3 ret
0:000> ln test1!CBell::CBell
(013610e0) test1!CBell::CBell | (01361100) test1!CWhistle::CWhistle
Exact matches:
test1!CBell::CBell (void)
0:000> u 013610e0 013610ff
test1!CBell::CBell:
013610e0 55 push ebp
013610e1 8bec mov ebp,esp
013610e3 51 push ecx
013610e4 894dfc mov dword ptr [ebp-4],ecx
013610e7 8b4dfc mov ecx,dword ptr [ebp-4]
013610ea e831000000 call test1!CWidget::CWidget (01361120)
013610ef 8b45fc mov eax,dword ptr [ebp-4]
013610f2 c7005cd43701 mov dword ptr [eax],offset test1!CBell::`vftable' (0137d45c)
013610f8 8b45fc mov eax,dword ptr [ebp-4]
013610fb 8be5 mov esp,ebp
013610fd 5d pop ebp
013610fe c3 ret
0:000> ln test1!CWidget::CWidget
(01361120) test1!CWidget::CWidget | (01361140) test1!std::basic_ostream >::operator<<
Exact matches:
test1!CWidget::CWidget (void)
0:000> u 01361120 0136113f
test1!CWidget::CWidget:
01361120 55 push ebp
01361121 8bec mov ebp,esp
01361123 51 push ecx
01361124 894dfc mov dword ptr [ebp-4],ecx
01361127 8b45fc mov eax,dword ptr [ebp-4]
0136112a c7006cd43701 mov dword ptr [eax],offset test1!CWidget::`vftable' (0137d46c)
01361130 8b45fc mov eax,dword ptr [ebp-4]
01361133 8be5 mov esp,ebp
01361135 5d pop ebp
01361136 c3 ret
0:000> ln test1!flip
d:\home\desktop\research\exp_def_ctor.cpp(8)
(01361060) test1!flip | (01361080) test1!main
Exact matches:
test1!flip (class CWidget *)
0:000> u 01361060 0136107f
test1!flip [d:\home\desktop\research\exp_def_ctor.cpp @ 8]:
01361060 55 push ebp
01361061 8bec mov ebp,esp
01361063 8b4508 mov eax,dword ptr [ebp+8]
01361066 8b10 mov edx,dword ptr [eax]
01361068 8b4d08 mov ecx,dword ptr [ebp+8]
0136106b 8b02 mov eax,dword ptr [edx]
0136106d ffd0 call eax
0136106f 5d pop ebp
01361070 c3 ret