tôi có mã này:Là một đối tượng được phép thay đổi hợp pháp loại của nó trong suốt cuộc đời của nó trong C++?
class Class {
public:
virtual void first() {};
virtual void second() {};
};
Class* object = new Class();
object->first();
object->second();
delete object;
mà tôi biên dịch với Visual C++ 10 với/O2 và có tháo gỡ này:
282: Class* object = new Class();
00403953 push 4
00403955 call dword ptr [__imp_operator new (4050BCh)]
0040395B add esp,4
0040395E test eax,eax
00403960 je wmain+1Ch (40396Ch)
00403962 mov dword ptr [eax],offset Class::`vftable' (4056A4h)
00403968 mov esi,eax
0040396A jmp wmain+1Eh (40396Eh)
0040396C xor esi,esi
283: object->first();
0040396E mov eax,dword ptr [esi]
00403970 mov edx,dword ptr [eax]
00403972 mov ecx,esi
00403974 call edx
284: object->second();
00403976 mov eax,dword ptr [esi]
00403978 mov edx,dword ptr [eax+4]
0040397B mov ecx,esi
0040397D call edx
285: delete object;
0040397F push esi
00403980 call dword ptr [__imp_operator delete (405138h)]
Lưu ý rằng tại 00403968
địa chỉ của đầu đối tượng (trong đó vptr
là được lưu trữ) được sao chép vào sổ đăng ký esi
. Sau đó, tại 0040396E
, địa chỉ này được sử dụng để truy xuất vptr
và giá trị vptr
được sử dụng để truy xuất địa chỉ của first()
. Sau đó, tại 00403976
, vptr
được truy xuất lại và được sử dụng để truy xuất địa chỉ của second()
.
Tại sao vptr được truy lục hai lần? Có thể các đối tượng có thể có vptr
của nó thay đổi giữa các cuộc gọi hoặc nó chỉ là một underoptimization?
Lạ. Tôi nghĩ rằng tất cả nên là một no-op. Nó có thể là một sự thiếu tối ưu hóa, nếu nó nhìn vào bên trong các chức năng, nó có thể thấy rằng không ai trong số họ thay đổi 'esi'. –