WEB开发网
开发学院软件开发VC ATL布幔之下的秘密 阅读

ATL布幔之下的秘密

 2006-07-22 22:55:08 来源:WEB开发网   
核心提示: 我们可以通过使用static_cast获得派生类虚函数表指针的偏移量,请看以下程序:程序16. #include <iostream>using namespace std;class Base1 {public:virtual void f() { }};class Base

我们可以通过使用static_cast获得派生类虚函数表指针的偏移量,请看以下程序:

程序16. #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 {
};
// 任意的非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;
}
ATL使用了一个定义在ATLDEF.H中的宏offsetofclass来做这件事,这个宏被定义为: #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;
}
派生类的内存布局为:

上一页  5 6 7 8 9 10 

Tags:ATL 之下 秘密

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接