C++从零开始之指针及其语义和运用
模块调用void Draw();来绘图,但绘图模块中(即函数Draw内部)可能根据当前绘图数据的情况(如场景复杂与否等)而决定不同的绘图方法,则可使用一全局函数指针void ( *g_pDraw )();,每次绘图模块会根据绘图情况设置此变量,而逻辑计算模块就变成( *g_pDraw )();而不再Draw();(此法不推荐,在此仅作为例子提出)。
对于成员指针,在《C++从零开始(九)》中已指出非静态成员变量映射的是偏移而不是地址,即成员变量指针不是内存块的引用,仅仅是偏移类型的数字的引用,而偏移类型的数字4个字节长,其指针反而可能8字节长,因此它不用于前面的传递的优化,也不能引用内存块,仅只有增加灵活性和语义需要。如一个结构是学生成绩,里面有40门学科的成绩,则欲计算平均分,如下:
则可书写一循环来简化计算,如: Student a; float avg = 0.0f; for( long i = 0; i < 40; i++ ) avg += a.*Student::pCourse[ i ]; avg /= 40.0f; 对于成员函数指针也是一样的,只用按照前述的规则和语义就可了解各类指针的运用。 引用内存块 这是指针的原始语义,当欲传递内存块时,就只能靠传递指针来实现(内存块是不能传递的),如: bool GetPersonInfo( PersonInfo *pInfo ); PersonInfo temp; GetPersonInfo( &temp ); // 使用返回的放在temp中的个人信息 上面的参数pInfo就是传递一个内存块给函数GetPersonInfo以让它将个人信息填在给定的内存块中以进行传递。如果PersonInfo* GetPersonInfo();,那么返回的指针所引用的那块内存块需要被释放,但使用GetPersonInfo的代码无法知道那内存块是如何分配的进而无法释放,这属于内存管理方面,在此不深入讨论。再如: bool GetMaxAndMin( long[10], long *max, long *min ); long a[10] = { 5, 3, 10 }, max, min; GetMaxAndMin( a, &max, &min ); 引用数字 这是借助地址类型的数字所带入的间接而形成的二级间接的运用,目的是被引用的数字的大小大于指针的大小时传递指针以减少传递成本。如上面的long[10]是40个字节,如果传递它的指针则只有4个字节,大大降低成本,如下: bool GetMaxAndMin( long(*)[10], long*, long* ); long a[10] = { 5, 3, 10 }, max, min; GetMaxAndMin( &a, &max, &min ); 这里数组a的传递就比之前有效率得多。再如之前的PersonInfo* GetPersonInfo();而不PersonInfo GetPersonInfo();也是出于sizeof(PersonInfo*)<sizeof(PersonInfo),也因此这样是愚蠢的:char Max( char*, char*, char* );。这里欲返回最大值,但sizeof(char*)>sizeof(char),不仅没提高反而降低了效率(对于32位编译器,这里将不是由于传递降低效率,而是间接引用数字降低效率)。 应注意指针能引用数字是由于二级间接,这导致多了一级无谓的引用——对内存块的引用,本只想传递数字,结果连装数字的内存块也传递了,将引起问题。如前面的GetMaxAndMin( &a, &max, &min );,执行后,数组a的内容可能被改变,因为记录a的内存块也被传过去了,函数GetMaxAndMin可任意修改传进去的内存块的内容,也就是数组a的内容。当函数GetMaxAndMin和调用它的代码不是同一个人编的时候,则前者就可以肆意破坏a的内容而导致后者发生问题,这被称作漏洞。所以当设计对外的接口时 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |