C++类的成员函数存储方式(是否属于类的对象)

今天在看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指针传给函数以指明以哪个类对象调用。

因此,前面的类型向下转换是没问题的,并不会造成越界访问~

你可能感兴趣的:(C++,成员函数,类型向下转换,共享成员函数代码)