最近工作不紧,抽空看了下C、C++的指针,发现了一些平时没注意到的指针用法和问题。
1、指针引用
void func1(MYCLASS* &pBuildingElement);
乍一看,怪怪的,看了下解释,细想一下和指针的指针类似:
void func1(MYCLASS** pBuildingElement);
看下面的例子:
...
MyClass* p = new MyClass;
func1(p);
...
func1的定义如下:
void func1(MyClass* pMyClass)
{
...
pMyClass = //其他对象的指针
...
}
第二条语句func1(p);在函数过程中只修改了pMyClass的值。并没有修改调用者的变量p的值。假设要在func1中修改p的值,现在就有两种方法:一是利用指针的指针,二是利用指针的引用。
以上代码可修改为:
//指针的指针
...
MyClass* p = NULL;
func1(&p);
...
func1的定义如下:
void func1(MyClass** pMyClass)
{
...
*pMyClass = new MyClass;
...
}
//指针的引用
...
MyClass* p = NULL;
func1(p);
...
func1的定义如下:
void func1(MyClass* &pMyClass)
{
...
pMyClass = new MyClass;
...
}
其实,它和前面指针的指针是一码事,只是语法有所不同。传递的时候不用传p的地址,而是直接传p本身。
至于说什么场合要使用这种方法,我会说,极少。MFC在其集合类中用到了它--例如,CObList,它是一个Cobjects指针列表。
Class CObList : public Cobject
{
……
// 获取/修改指定位置的元素
Cobject*& GetAt(POSITION position);
Cobject* GetAt(POSITION position) const;
};
这里有两个GetAt函数,功能都是获取给定位置的元素。区别何在呢?
2、数据指针
常规数据指针和成员数据指针
这里主要涉及成员数据指针的内容。
struct MyStruct{
int value;
int key;
}
struct MyStruct me;
struct MyStruct* pMe;
定义成员数据指针:
int MyStruct::* pMV = &MyStruct::value;
int MyStruct::* pMK = &MyStruct::key;
这种指针的用途是用于取得结构成员在结构内的地址。我们可以通过该指针来访问成员数据:
int value = pMe->*pMV; // 取得pMe的value成员数据。
int key = me.*pMK; // 取得me的key成员数据。
那么,在什么场合下会使用到成员数据指针呢?
确实,成员指针本来就不是一种很常用的指针。不过,在某些时候还是很有用处的。我们先来看看下面的一个函数:
int sum(MyStruct* objs, int MyStruct::* pm, int count)
{
int result = 0;
for(int i = 0; i < count; ++i)
result += objs[i].*pm;
return result;
}
函数功能:给定count个MyStruct结构的指针,计算出给定成员数据的总和
使用:
MyStruct me[10] =
{
{1,2},{3,4},{5,6},{7,8},{9,10},{11,12},{13,14},{15,16},{17,18},{19,20}
};
//计算10个MyStruct结构的value成员的总和
int sum_value = sum(me, &MyStruct::value, 10);
//计算10个MyStruct结构的key成员的总和
int sum_key = sum(me, &MyStruct::key, 10);
好处:若使用常规指针,需要为每个成员分别写一个函数。