class Window
{
public:
Window()
{
m_i = 0;
}
virtual void func()
{
++m_i;
}
protected:
int m_i;
};
class SpecialWindow: public Window
{
public:
virtual void func()
{
//static_cast<Window*>(this)->func(); 1
//static_cast<Window>(*this).func(); 2
//Window::func(); 3
std::cout << m_i << std::endl;
}
};
如上所示的代码中,派生类函数func中的三行存在的问题:
1. 1行其实是一个死循环,由于函数的派生关系,将this指针修改为基类的指针然后调用func函数,因为this其实是派生类SpecialWindow,所以还是调用派生类的func函数,导致死循环
2. 2行其实存在问题:在基类Window中修改了m_i的值,但是运行程序就会发现,其实m_i的值没有修改,因为强制类型转换调用的是稍早转型操作所建立的*this对象之base class部分的副本,因此对于本this没有影响,因为每一个类都会存在一个this指针,如果this不一致就会导致基类的成员变量的值不一致,如下面的汇编代码所示,其实这里创建了一个临时的对象
static_cast<Window>(*this).func();
011117B2 mov eax,dword ptr [ebp-14h]
011117B5 push eax
011117B6 lea ecx,[ebp-0E4h]
011117BC call Window::Window (1111203h)
011117C1 mov dword ptr [ebp-0ECh],eax
011117C7 mov ecx,dword ptr [ebp-0ECh]
011117CD mov dword ptr [ebp-0F0h],ecx
011117D3 mov dword ptr [ebp-4],0
011117DA mov edx,dword ptr [ebp-0F0h]
011117E0 mov dword ptr [ebp-0F4h],edx
011117E6 mov eax,dword ptr [ebp-0F4h]
011117EC mov edx,dword ptr [eax]
011117EE mov esi,esp
011117F0 mov ecx,dword ptr [ebp-0F4h]
011117F6 mov eax,dword ptr [edx]
011117F8 call eax
011117FA cmp esi,esp
011117FC call @ILT+465(__RTC_CheckEsp) (11111D6h)
01111801 mov dword ptr [ebp-4],0FFFFFFFFh
01111808 lea ecx,[ebp-0E4h]
0111180E call Window::~Window (11112B7h)
3. 是正常的调用方式,也是程序推荐的调用方式