C++类的成员函数存储方式(是否属于类的对象)
2016-07-10 15:42
447 查看
今天在看TAF源码的时候,发现下面一段有趣的代码:
我们看一看这行代码:
此处的proxy 的类型是T,具体来说就是GetSmallerPrx
(更具体的说,是taf::TC_AutoPtr < MobileAssist::GetSmallerProxy >)。
而pServantProxy的类型是ServantProxy *。
将ServantProxy 类型的指针强制转换成GetSmallerProxy类型的指针,而ServantProxy是GetSmallerProxy的基类——我的第一反应是——这是非常危险的!比如如果GetSmallerProxy访问了某个ServantProxy没有的成员变量,将造成越界访问。
不过事实上,上面的假设并不成立——GetSmallerProxy没有新的成员变量。
![](http://img.blog.csdn.net/20160710153805442)
但是有新的成员函数——而事实是,子类特有的成员函数是可以正常访问的:
![](http://img.blog.csdn.net/20160710153834473)
这是不是说明,类的成员函数并不占用类对象的内存空间(如果占用的话,此处的访问将越界)。
所以我做了一个简单的实验:
结论:成员函数是不占用类对象内存空间的。
一般情况下,同一个类的不同对象,共享成员函数的代码。成员函数的代码存储在对象空间之外。换句话说,成员函数的代码,都不占据对象的存储空间。所以类的成员函数,对于类来讲,一方面是逻辑上的“属于”,一方面是物理上的“不依赖”。
所以如果成员函数未使用任何成员变量的话,不管是不是static的,都能正常工作。在调用成员函数时,将this指针传给函数以指明以哪个类对象调用。
因此,前面的类型向下转换是没问题的,并不会造成越界访问~
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语言实验——保留整数
- C++创建虚拟机调用JAVA类
- 坦克大战----Ubuntu终端游戏
- leetcode_c++:哈希:word pattern(290)
- leetcode_c++:哈希:H-Index(274)
- leetcode_c++:哈希: Valid Anagram(242)
- "const" & "#define"
- 读Advanced C and C++ Compiling
- leetcode_c++:哈希: Isomorphic Strings(205)
- Kruskal最小生成树
- 杂谈c++与java
- 贪心算法-Huffman编码
- leetcode_c++:哈希:Count Primes (204)
- 洛谷1341 无序字母对 解题报告
- C++位运算知识点
- C语言实验——保留字母
- C语言 百炼成钢25
- C语言atoi()函数:将字符串转换成int(整数)
- C语言link()函数:建立文件连接
- C语言lseek()函数:移动文件的读写位置