1、成员指针(pointer to member)包含类的类型以及成员的类型。成员指针只应用于类的非static成员。static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员,static成员指针是普通指针。通过指定函数的返回类型,形参表(类型和数目,是否为const)和所属类来定义成员函数的指针。
2、使用类成员的指针
类似于成员访问操作符 . 和 ->,.* 和 -> 是两个新的操作符,它们使我们能够将成员指针绑定到实际对象。这两个操作符的左操作数必须是类类型的对象或类类型的指针,右操作数是该类型的成员指针。
• 成员指针解引用操作符(.*)从对象或引用获取成员。
• 成员指针箭头操作符(->*)通过对象的指针获取成员。
示例代码
#include "iostream"
#include "string"
#include "vector"using namespace std;class Screen
{
public:Screen(std::string StrCon = "Here", std::string::size_type myCursor = 12):contents(StrCon), cursor(myCursor){}typedef std::string::size_type index;char get() const{return '1';};char get(index ht, index wd) const{return '2';};
public:std::string contents;index cursor;index height, width;
};int main()
{//定义的成员指针从右向左读string Screen::*ps_Screen = &Screen::contents; char (Screen::*pmf)() const = &Screen::get;char (Screen::*pmf1)(Screen::index,Screen::index) const = &Screen::get;Screen myScreen;//使用成员函数的指针char c1 = myScreen.get();char c2 = (myScreen.*pmf)();cout << c1 << " " << c2 << endl; // 1 1Screen *pScreen = &myScreen;c1 = pScreen->get();c2 = (pScreen->*pmf)();cout << c1 << " " << c2 << endl; // 1 1c1 = pScreen->get(0, 0);c2 = (pScreen->*pmf1)(0, 0);cout << c1 << " " << c2 << endl; // 2 2//使用数据成员的指针Screen::index Screen::*pIndex = &Screen::cursor;Screen::index ind1 = myScreen.cursor;Screen::index ind2 = myScreen.*pIndex;cout << ind1 << " " << ind2 << endl;return 1;
}
注意: (myScreen.*pmf)();不能省略括号。因为()的优先级比*高,所以如果省略括号,则解析成:myScreen.*(pmf());这段代码的意思是:调用名为pmf的函数,把函数的返回值绑定到成员对象操作符(.*)的指针。
2)成员指针函数表
函数指针和成员函数指针的一个公共用途是,将它们存储在函数表中。函数表是函数指针的集合,在运行时从中选择给定调用。
示例代码
#include "iostream"
#include "string"
#include "vector"using namespace std;class Screen {
public:// other interface and implementation members as before//Screen& home(){}; // cursor movement functions//Screen& forward(){};//Screen& back(){};//Screen& up(){};//Screen& down(){};int home() {return 1;}int forward(){return 1;}int back() {return 1;}int up(){return 1;}int down(){return 1;}
public:// other interface and implementation members as before// Action is pointer that can be assigned any of the cursor movement members//typedef Screen& (Screen::*Action)();typedef int (Screen::*Action)();static Action Menu[]; // function table
public:// specify which direction to moveenum Directions { HOME, FORWARD, BACK, UP, DOWN };Screen& move(Directions);
};
Screen& Screen::move(Directions cm)
{// fetch the element in Menu indexed by cm// run that member on behalf of this object(this->*Menu[cm])();return *this;
}
Screen::Action Screen::Menu[] =
{ &Screen::home,&Screen::forward,&Screen::back,&Screen::up,&Screen::down,
};
int main()
{Screen myScreen;myScreen.move(Screen::HOME); // invokes myScreen.homemyScreen.move(Screen::DOWN); // invokes myScreen.downreturn 1;
}
3、枚举的大小
示例代码
#include "iostream"
#include "string"
#include "vector"using namespace std;
class A
{
public:enum MyData{M1, M2, M3, M4};static int iMy;
};
int A::iMy = 1;
enum MyData{M1, M2, M3, M4};
int main()
{A Data1;cout << A::M1 << " " << A::M2 << " " << A::M3 << " "<< endl; //0 1 2cout << Data1.M1 << " " << Data1.M2 << " " << Data1.M3 << endl; //0 1 2//cout << A::MyData << endl; //“A::MyData”: 将此类型用作表达式非法cout << sizeof(A) << endl; //1cout << sizeof(Data1) << endl; //1cout << sizeof(MyData) << endl; //4MyData Data2;cout << sizeof(Data2) << endl; //4return 1;
}
枚举的大小为一个整形数据的大小。但是,在类中,求类的大小时,不计算数据成员的大小,同样也不计算枚举成员的大小。类中定义的枚举数据成员可以通过类名和作用域直接引用。
http://www.cnblogs.com/mydomain/archive/2011/04/30/2033483.html
4、我们需要注意的是,静态函数没有this指针。但是,类和类对象共享一份类中定义的静态数据成员。在非静态函数中可以通过this指针来引用这些静态数据成员。
示例代码
#include "iostream"
#include "string"
#include "vector"using namespace std;
class A
{
public:void Print(){cout << this->iMy << endl;}
public:static int iMy;
};
int A::iMy = 1;
int main()
{A Data1;Data1.Print(); //1cout << A::iMy << endl; //1Data1.iMy = 2;A Data2;cout << Data2.iMy << endl; //2return 1;
}
http://www.cnblogs.com/mydomain/archive/2011/03/22/1991449.html
5、函数指针的赋值
示例代码
#include <iostream>
using namespace std;char myfun()
{return '1';
}
char* myfun2()
{char *p = (char*)malloc(3);return p;
}int main()
{char (*p)() = myfun;//char* (p1()) = &myfun2; //error,无法从“char *(__cdecl *)(void)”转换为“char *(void)char* (*p1)() = &myfun2;//char *p() = myfun(); //注意,这样做是错误的,p被定义为一个函数,返回char*,而不是函数指针。return 1;
}