指针问题!!做指针总结时的心得及发现的问题!!各位大师请指点一二!回者有分
先说两句题外话.最近,在研读mfc的源代码,研读过程中倍感自己C++的功底不足,既要从mfc的设计上思考,又得从C++的语法上思考,
十分的吃力.虽说是收获不小,但总觉得,不是个办法.因此,现在先放下了mfc来补C++.
关键的问题还是在指针上,自己被感指针功能的强大,并且深刻的意识到学习C/C++不会使用指针是绝对行不通的,因此放下手中的mfc来
做一个指针用法的小结.并希望此次小结能让自己的C++水平上升一个层次.
_____________________________________________
由于自己还是一个大二的学生(马上大三了),实践经验少之又少,自己的总结多数来自书籍,还有自己少之又少的代码编写过程中.可
能总结了不少错误的原则,还望各位大师帮学生一个忙.指点一二.免的辛辛苦苦总结了半天还把自己误入歧途啊!哈哈哈...
#############################################
小结一.
把指针变量作为函数参数的用途.
1.用来传递大型对象(避免按值传递时花费在拷贝上的时间).
这是我的理解:把指向大型对象的指针传入函数体中,意味着函数有了操作该对象的功能.通过该指针操作了一块不属于该函数局部域的内
存块.而花费的开销只是在函数体内分配了该对象指针的空间,传参时只是对对象的指针进行了一下拷贝.因此在时间和空间上都提高了效率
.
//该总结来自C++ Primer,
2.用于面向对象编程中,经常把基类指针作为函数的参数,根据不同的对象实例的指针实现多态的操作.
小生在看mfc原代码的时候,体会相当的深刻,熟悉mfc的类的层次结构的大师应该有很深的体会.整个mfc提供的那么多类,就是通过指针和
继承把一个个不相干的类联系到了一起.最后就出现了Application Framework这样迷人的东西.
3.数组作为函数的参数.
数组作为函数的参数的实质,函数的参数是一个该类型的指针变量。而该指针变量指向数组的首地址。
所以以下代码的实质是一样的。
void F( char *pchar );
void F( char buf[] );
这里出现这样的问题。
在全局域中定义
main()
{
int a[10];
sizeof(a);//返回的数组单元的长度。
//所以通过
sizeof(a)/sizeof(a[0]);
//就可以计算出数组的长度。
}
而定义函数
f( int *p )
{
sizeof(p);//计算出的是该指针变量单元的长度
}
因此
main()
{
int a[10];
f(a);//函数内部则不能得到数组的长度,因此难以对数组进行操作
}
因此在编写操作数组的函数中,一般设置两个参数,一般的写发如下.
template<class Type>
void f( Type *p , int size );
//该终结来自小生的一次实验代码和C++ primer
4.指向函数的指针作为函数的参数
为什么要使用函数指针作为函数的参数。
我的理解:在一个复杂而又想让他具有通用功能的过程中(函数)中,对参数数据的操作在功能具有一定的相似性,但又有明显的差异和不同
!因此需要使用不同的函数来处理不同的数据,或者处理相同的数据来达到不同的效果!从而支持某函数(过程)的实现。
一个经典的用法是:
编写遍历二叉树的函数。
遍历只是一个手段,而最终的目的是为了对树内的数据进性行操作!
所以函数的定义写成这样
void BinaryTree::inorder( void(*pfn)( node& item ) )
这样只需要编写返回值为void 参数类型为 node&类型的函数就可以对选择遍历操作时对树内结点的操作。方法是把函数指针传入遍历的函数
就可以啦!
5.指向指针的指针作为函数的参数。
这种用法到现在为止小生还没有见过。只是在"谭浩强"的C语言书中见过。但觉得其价值自己提炼不出来。
这里向各位大师请教,如果有写过这样的函数,请忙小生总结一下。这种类型的函数的用法!
注意:
这里我觉得有一个问题值得注意!
指针作为函数的参数不一定指向切实的对象。
因此在函数体内部做这样的检查是必要的,避免发生,难以发现的错误。
if( p!=NULL )
{
...
}
else
{
//发出警告
}
以上是小生对指针做为函数参数的总结
——————————————————————————————————————————————————————————————
二。返回值是函数指针的函数。
返回值是函数指针的函数,涉及到复杂的内存管理问题。
自己更是头大的要命。所以我把这个问题避开。以后做内存管理的总结时在深入。
在这里我只谈一个mfc框架中普遍的用法。
通过函数返回的某个类型的指针,当然在mfc初始化的时候这个指针已经指向确切的对象。通过该指针就可以为别的类提供必要的服务。
例如:mfc中经典的view/document类中
CMyView::OnDraw( CDC* pDC )
{
CMyDoc *pDoc=GetDocument();//这个地方就获得了CMyDocument对象使用权限,这样就可以在OnDraw函数中为之提供服务了。
ASSET_VALID(pDC);
//// TODO: add draw code for native data here
}
通过这样的方法,就在没有定义在CMyView类内部定义CMyDocument对象的情况下使用了CMyDocument的对象。
避免了使用组合的方法。当然,通过这样的方法,切实的把两个类的使用融合到了一起,堪称经典。
在mfc的整个框架中有好多类都是这样指针联系起来协同工作的。
这也是我看mfc代码看不下去的巨大原因!设计太过巧妙。自己指针的功底又不足啊。
——————————————————————————————————————————————————————————————
这就是自己目前阶段的总结。肯定有好多漏洞吧!
还望各位大师给小生一些指点。
小生在这里先谢过了!!