在这一系列的文章里,我将和大家一起讨论ATL的底层工作和ATL所使用到的技术。如果你只想尝试写个普通的ATL控件,这篇文章对你一点帮助
都没有;如果你想更好的学会使用ATL,认真往下看把。
我们先来讨论一个类(Class)的存储配置。首先来写一个类,这个类没有任何数据成员,然后来看看他的内存结构。
程序1:
#include <iostream>
using namespace std;
class Class{
};
int main()
{
Class objClass;
cout << \"Size of object is = \" << sizeof(Class) << endl;
cout << \"Address of object is = \" << &objClass << endl;
return 0;
}
程序输出:
Size of object is = 1
Address of object is = 0012FF7C
现在,如果我们往类里添加数据成员,他的大小会将等于所有数据成员所占内存的和。在模版类(template class)中,也是这样。现在,让我
们来看看模版类Point。
程序2:
#include <iostream>
using namespace std;
template <typename T>
class CPoint{
T m_x;
T m_y;
};
int main()
{
CPoint<int> objPoint;
cout << \"Size of object is = \" << sizeof(objPoint) << endl;
cout << \"Address of object is = \" << &objPoint << endl;
return 0;
}
程序输出:
Size of object is = 8
Address of object is = 0012FF78
现在,我们也添加一个继承类到这个程序,我们用Point3D类来继承Point类,同时来看看程序的内存结构。
程序3:
#include <iostream>
using namespace std;
template <typename T>
class CPoint{
T m_x;
T m_y;
};
template <typename T>
class CPoint3D : public CPoint<T>
{
T m_z;
};
int main()
{
CPoint<int> objPoint;
cout << \"Size of Point is = \" << sizeof(objPoint) << endl;
cout << \"Address of Point is = \" << &objPoint << endl;
CPoint3D<int> objPoint3D;
cout << \"Size of Point3D is = \" << sizeof(objPoint3D) << endl;
cout << \"Address of Point3D is = \" << &objPoint3D << endl;
return 0;
}
程序输出:
Size of Point is = 8
Address of Point is = 0012FF78
Size of Point3D is = 12
Address of Point3D is = 0012FF6C
这个程序说明了派生类的内存结构。派生类所占用的内存总数是基类的所有数据成员和该派生类所有数据成员所占内存的和。
如果把虚函数也添加进来,那这个问题就更有趣了。我们来看看这个程序。
程序4:
#include <iostream>
using namespace std;
class Class
{
virtual void fun()
{
cout << \"Class::fun\" << endl;
}
};
void main()
{
Class objClass;
cout << \"size of class = \" << sizeof(objClass) << endl;[Page]
cout << \"Address of class = \" << & objClass << endl;
}
程序输出:
size of class = 4
Address of class = 0012FF7C
如果我们添加一个以上的需函数,那么情况会变得更有去。
程序5:
#include <iostream>
using namespace std;
class Class
{
virtual void fun1()
{
cout << \"Class::fun\" << endl;
}
virtual void fun2()
{
cout << \"Class::fun2\" << endl;
}
virtual void fun3()
{
cout << \"Class::fun3\" << endl;
}
};
void main()
{
Class objClass;
cout << \"size of class = \" << sizeof(objClass) << endl;
cout << \"Address of class = \" << & objClass << endl;
}
程序的输出和上面一样。我们来做多点实验,使我们能更好地理解他。
程序6:
#include <iostream>
using namespace std;
class CPoint
{
int m_x;
int m_y;
public:
virtual ~CPoint(){
};
};
void main()
{
CPoint objPoint;
cout << \"size of Point = \" << sizeof(objPoint) << endl;
cout << \"Address of Point = \" << &objPoint << endl;
}
程序输出:
size of Point = 12
Address of Point = 0012FF68
这个程序的输出告诉我们,无论你在类里添加多少个虚函数,他的大小只增加一个int数据类型所占的内存空间,例如在Visual C++ 他增加4字
节。他表示有三块内存给这个类的整数,一个给m_x,一个给m_y,还有一个用来处理被调用的虚函数的虚指针。首先来看一看新的一块内存,也
就是虚函数指针所占内存,在该对象的最开始头(或者最后)。我们可以通过直接访问对象所占的内存块来调用虚函数。只要把对象的地址保
存到一个int类型指针,然后使用指针算法的魔术(The magic of pointer arithmetic)就能够调用他了。
程序7:
#include <iostream>
using namespace std;
class CPoint {
public:
int m_ix;
int m_iy;
CPoint(const int p_ix = 0, const int p_iy = 0) :