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 1 Screen *pScreen = &myScreen; c1 = pScreen->get(); c2 = (pScreen->*pmf)(); cout << c1 << " " << c2 << endl; // 1 1 c1 = 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 move enum 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.home myScreen.move(Screen::DOWN); // invokes myScreen.down return 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 2 cout << Data1.M1 << " " << Data1.M2 << " " << Data1.M3 << endl; //0 1 2 //cout << A::MyData << endl; //“A::MyData”: 将此类型用作表达式非法 cout << sizeof(A) << endl; //1 cout << sizeof(Data1) << endl; //1 cout << sizeof(MyData) << endl; //4 MyData Data2; cout << sizeof(Data2) << endl; //4 return 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(); //1 cout << A::iMy << endl; //1 Data1.iMy = 2; A Data2; cout << Data2.iMy << endl; //2 return 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; }