ATL布幔之下的秘密
2006-07-22 22:55:08 来源:WEB开发网我们可以通过使用static_cast获得派生类虚函数表指针的偏移量,请看以下程序:
程序16. #include <iostream>
ATL使用了一个定义在ATLDEF.H中的宏offsetofclass来做这件事,这个宏被定义为:
using namespace std;
class Base1 {
public:
virtual void f() { }
};
class Base2 {
public:
virtual void f() { }
};
class Base3 {
public:
virtual void f() { }
};
class Drive : public Base1, public Base2, public Base3 {
};
// 任意的非0值,因为0乘任何数都得0
#define SOME_VALUE 1
int main() {
cout << (DWORD)static_cast<Base1*>((Drive*)SOME_VALUE)-SOME_VALUE << endl;
cout << (DWORD)static_cast<Base2*>((Drive*)SOME_VALUE)-SOME_VALUE << endl;
cout << (DWORD)static_cast<Base3*>((Drive*)SOME_VALUE)-SOME_VALUE << endl;
return 0;
}#define offsetofclass(base, derived) \
这个宏返回了在派生类对象模型中基类虚函数表指针的偏移量,让我们来看看下面这个例子:
((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING)
程序17. #include <windows.h>
派生类的内存布局为:
#include <iostream>
using namespace std;
class Base1 {
public:
virtual void f() { }
};
class Base2 {
public:
virtual void f() { }
};
class Base3 {
public:
virtual void f() { }
};
class Drive : public Base1, public Base2, public Base3 {
};
#define _ATL_PACKING 8
#define offsetofclass(base, derived) \
((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING)
int main() {
cout << offsetofclass(Base1, Drive) << endl;
cout << offsetofclass(Base2, Drive) << endl;
cout << offsetofclass(Base3, Drive) << endl;
return 0;
}
更多精彩
赞助商链接