ATL布幔之下的秘密(2)
2006-07-22 22:55:03 来源:WEB开发网ATL的主要思想就是让COM组件尽可能的小,但是由于这一行为,接口类的构造函数就会拥有很多不必要的代码。为了解决这一问题,ATL引入了一个宏ATL_NO_VTABLE,它定义在ATLDEF.H中:
#define ATL_NO_VTABLE __declspec(novtable)
__declspec(novtable)为Microsoft C++扩展的类属性。它会使编译器不产生初始化虚函数表指针和虚函数表的代码,这样一来就减少了生成代码的尺寸。那么,我们来修改一下我们的代码,这样就能更好的明白这一属性究竟能为我们做什么了。
程序31. #include <iostream>
程序的输出为:
using namespace std;
class Base {
public:
Base() {
cout << "In Base" << endl;
cout << "Virtual Pointer = " << (int*)this << endl;
cout << "Address of Vtable = " << (int*)*(int*)this << endl;
cout << "Value at Vtable 1st entry = " << (int*)*((int*)*(int*)this+0) << endl;
cout << "Value at Vtable 2nd entry = " << (int*)*((int*)*(int*)this+1) << endl;
cout << endl;
}
virtual void f1() = 0;
virtual void f2() = 0;
};
class Drive : public Base {
public:
Drive() {
cout << "In Drive" << endl;
cout << "Virtual Pointer = " << (int*)this << endl;
cout << "Address of Vtable = " << (int*)*(int*)this << endl;
cout << "Value at Vtable 1st entry = " << (int*)*((int*)*(int*)this+0) << endl;
cout << "Value at Vtable 2nd entry = " << (int*)*((int*)*(int*)this+1) << endl;
cout << endl;
}
};
class __declspec(novtable) MostDrive : public Drive {
public:
MostDrive() {
cout << "In MostDrive" << endl;
cout << "Virtual Pointer = " << (int*)this << endl;
cout << "Address of Vtable = " << (int*)*(int*)this << endl;
cout << "Value at Vtable 1st entry = " << (int*)*((int*)*(int*)this+0) << endl;
cout << "Value at Vtable 2nd entry = " << (int*)*((int*)*(int*)this+1) << endl;
cout << endl;
}
virtual void f1() { cout << "MostDrive::f1" << endl; }
virtual void f2() { cout << "MostDrive::f2" << endl; }
};
int main() {
MostDrive d;
return 0;
}In Base
这个程序有另外一个结果,也就是Drive和MostDrive类拥有相同的虚函数表地址,但是Base类却不同。事实上,这就是由于我们没有对Base类使用__declspec(novtable)属性的缘故。现在,我们来对继承的Drive类也使用相同的属性,也就是__declspec(novtable)。
Virtual Pointer = 0012FF7C
Address of Vtable = 0046C0CC
Value at Vtable 1st entry = 00420E60
Value at Vtable 2nd entry = 00420E60
In Drive
Virtual Pointer = 0012FF7C
Address of Vtable = 0046C0B4
Value at Vtable 1st entry = 00420E60
Value at Vtable 2nd entry = 00420E60
In MostDrive
Virtual Pointer = 0012FF7C
Address of Vtable = 0046C0B4
Value at Vtable 1st entry = 00420E60
Value at Vtable 2nd entry = 00420E60
更多精彩
赞助商链接