您的位置:首页 > 其它

成员指针(pointer-to-member)

2015-04-24 12:14 357 查看
指针是一个指向某内存空间的地址变量;指针可以在运行时改变指向内存,它可以指向数据也可以指向函数。

C++“成员指针”和C指针具有相同的概念,但是“成员指针”的指向范围只在特定的类里面。

这里有一个问题:指针实际就是一个(矢量)地址,但是在类里面是没有地址的。所以“成员指针”的地址是一个类中的相对偏移地址。如果想得到“成员指针”的实际地址,必须通过类的对象来得到。

说简单点:C++的“成员指针”和“成员指针函数”对应C中的“指针”和“函数指针”,区别就是“成员指针***”的范围限定在一个类里面(而类没有实例化之前,地址都是相对偏移地址)。

那么“成员指针”的作用是什么呢?我想主要的就是可以在运行时改变它的指向(晚绑定)。我们利用“晚绑定”实现了C++的多态,我们可以利用“晚绑定”来实现接口。

好了,code wins argument(代码胜于雄辩,刚学到的),直接看代码。

//基于x86 64bit CPU
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

class cTest{};
typedef void (cTest::*test_func_ptr)(void);
typedef void (*func_ptr)(void);
/*
这里sizeof(test_func_ptr)输出为16,而sizeof(func_ptr)输出为8。我想了很久没有想出答案,google之后找到了一个这样的链接。 http://blogs.msdn.com/b/oldnewthing/archive/2004/02/09/70002.aspx 我只想说:C++的水太深了。
*/
int testSizeofPointerToMember()
{
  int a = sizeof(test_func_ptr);
  int b = sizeof(func_ptr);
  cout<<a<<endl;
  cout<<b<<endl;
  cout<<sizeof(cTest)<<endl;
}

class cData 
{
	public:
	int a, b, c;
	int *ptmInt;
	void print() const 
	{
		cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
	}
};
/*
成员指针的例子
*/
int testPointerToMember() 
{

	cData data;
	cData *dp = &data;
	cData test;

	int cData::*ptmInt= &cData::a; //成员指针
	dp->*ptmInt = 47;	
	
	ptmInt = &cData::b;	
	data.*ptmInt = 48;
	
	ptmInt = &cData::c;	
	dp->*ptmInt = 49;
		
	//pmInt =&Data::pmInt;//cannot convert 'int* Data::*' to 'int Data::*' in assignment
    	
	data.print();
	dp->print();
	test.print();
	
	cout<<sizeof(cData)<<endl;

	return 1;
}

class cBase
{
public:
  virtual int func(char* c=0)
  {
    cout<<"cBase::func(char*)"<<endl;
    return 1;
  }
};  
class cDerivedFromBase:public cBase
{
public:
  virtual int func(char* c=0)
  {
    cout<<"cDerivedFromBase::func(char*)"<<endl;
    return 1;
  }
};
class cOther
{
public:
  void func(int i=0)
  {
    cout<<"cOther::func(int)"<<endl;
  }
};
 
/*
成员指针函数的例子
*/ 
int testPointerToMemberFunction()
{
  typedef int (cBase::*bFPTR) (char*);
  typedef int (cDerivedFromBase::*dFPTR) (char*);
  typedef void (cOther::*oFPTR) (int);

  bFPTR bptr = &cBase::func;
  dFPTR dptr = &cDerivedFromBase::func;
  oFPTR optr = &cOther::func;

  cBase objBase;
  ( objBase.*bptr )("xyz");
  ( objBase.*(bFPTR)dptr )("xyz");
  
  cDerivedFromBase objDerive;
  ( objDerive.*(dFPTR)bptr )("xyz");
  ( objDerive.*dptr )("xyz");
    
  cOther objOther;
  ( objOther.*optr )(3);
 
}

class cMyString
{//An abstract printing myStr
public:
  void Copy(char * buff, const char * source)
  {
    strcpy(buff, source);
  }
  void Append(char * buff, const char * source)
  {
    strcat(buff, source);
  }
}; 
enum OPTIONS { COPY, APPEND };
typedef void(cMyString::*PTR) (char*, const char*); 
void working(OPTIONS option, cMyString* myStr, char* buff, const char* infostr)
{
  PTR pmf[2]= {&cMyString::Copy, &cMyString::Append};
 
  switch (option)
  {
  case COPY:
    (myStr->*pmf[COPY])(buff, infostr);//成员指针函数数组
    break;
  case APPEND:
    (myStr->*pmf[APPEND])(buff, infostr);
    break;
  }
}

/*
成员指针函数数组
*/ 
int testPointerToMemberFunctionArray()
{
  cMyString myStr;
  char buff[40];
 
  working(COPY, &myStr, buff, "Strings ");  
  working(APPEND, &myStr, buff, "are concatenated! ");
 
  cout<<buff<<endl;
}  

int main()
{
  cout<<"*****************testSizeofPointerToMember******************"<<endl;
  testSizeofPointerToMember();
  
  cout<<"*****************testPointerToMember******************"<<endl;  
  testPointerToMember(); 
  
  cout<<"*****************testPointerToMemberFunction******************"<<endl;
  testPointerToMemberFunction();
  
  cout<<"*****************testPointerToMemberFunctionArray******************"<<endl;
  testPointerToMemberFunctionArray();
  return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: