今天在看TAF源码的时候,发现下面一段有趣的代码:
getSmallerProxyPrx = Application::getCommunicator()->stringToProxy<GetSmallerPrx>(MobileAssist.JiangeSmallerServer.GetSmaller);
//此处T为GetSmallerPrx
template<class T> T stringToProxy(const string& objectName,const string& setName="")
{
T prx = NULL;
stringToProxy<T>(objectName, prx,setName);
return prx;
}
//此处T为GetSmallerPrx
template<class T> void stringToProxy(const string& objectName, T& proxy,const string& setName="")
{
//getServantProxy中new ServantProxy()并返回
ServantProxy * pServantProxy = getServantProxy(objectName,setName);
//将ServantProxy类型的指针强制转换为GetSmallerProxy类型的指针
//并放入GetSmallerProxy类型的智能指针中
proxy = (typename T::element_type*)(pServantProxy);
}
我们看一看这行代码:
proxy = (typename T::element_type*)(pServantProxy);
此处的proxy 的类型是T,具体来说就是GetSmallerPrx
(更具体的说,是taf::TC_AutoPtr < MobileAssist::GetSmallerProxy >)。
而pServantProxy的类型是ServantProxy *。
(typename T::element_type*)(pServantProxy)
将ServantProxy 类型的指针强制转换成GetSmallerProxy类型的指针,而ServantProxy是GetSmallerProxy的基类——我的第一反应是——这是非常危险的!比如如果GetSmallerProxy访问了某个ServantProxy没有的成员变量,将造成越界访问。
不过事实上,上面的假设并不成立——GetSmallerProxy没有新的成员变量。
但是有新的成员函数——而事实是,子类特有的成员函数是可以正常访问的:
这是不是说明,类的成员函数并不占用类对象的内存空间(如果占用的话,此处的访问将越界)。
所以我做了一个简单的实验:
#include <iostream>
using namespace std;
class A
{
public:
A(){}
~A(){}
};
class B
{
public:
B(){}
virtual ~B(){}
};
class C
{
public:
C() {}
~C() {}
int add(int a, int b)
{
return a+b;
}
};
int main()
{
cout << "Size(A) = " << sizeof(A) << endl;
cout << "Size(B) = " << sizeof(B) << endl;
cout << "Size(C) = " << sizeof(C) << endl;
return 0;
}
./testClassFun
Size(A) = 1
Size(B) = 8
Size(C) = 1
结论:成员函数是不占用类对象内存空间的。
一般情况下,同一个类的不同对象,共享成员函数的代码。成员函数的代码存储在对象空间之外。换句话说,成员函数的代码,都不占据对象的存储空间。所以类的成员函数,对于类来讲,一方面是逻辑上的“属于”,一方面是物理上的“不依赖”。
所以如果成员函数未使用任何成员变量的话,不管是不是static的,都能正常工作。在调用成员函数时,将this指针传给函数以指明以哪个类对象调用。
因此,前面的类型向下转换是没问题的,并不会造成越界访问~
时间: 2024-11-04 14:23:15