类的成员函数的指针
来源:互联网 发布:家里网络接线盒没连 编辑:程序博客网 时间:2024/04/30 12:26
前面一篇文章《函数的指针 》介绍了全局函数的指针,现在我们再来介绍一下成员函数的指针。
成员函数指针的定义:
一般形式
Return_Type (Class_Name::* pointer_name) (Argument_List);
用typedef简化的形式
Typedef Return_Type (Class_Name::* FuncPtr_Type) (Argument_List);
FuncPtr_Type pFunc = NULL;//pFunc为成员函数指针的指针变量
成员函数指针的调用
(obj.*pPrint)(Argument_List);//obj为类的对象
(pObj->*pPrint)(Argument_List);//pObj为类的对象的指针
举个例子如下:
#include "stdafx.h"#include <iostream> #include <string> using namespace std; class Person{private:int age;float weight;float height; public:Person(int _age, float _weight, float _heigth){age = _age;weight = _weight;height = _heigth;} void PrintPersonInfo(){cout << "age: " << age << " weight: " << weight << " height: " << height << endl;}}; typedef void (Person::*PrintFunc)();PrintFunc pPrint = &Person::PrintPersonInfo; void testMemberFuncPtr(){Person child(2, 15.2, 0.45);(child.*pPrint)();//把pPrint指针邦定到child对象 Person adult(22, 60.2, 1.75);Person* pAdult = &adult;(pAdult->*pPrint)();//把pPrint指针邦定到pAdult指向的对象(即adult对象)}
结果:
age: 2 weight: 15.2 height: 0.45
age: 22 weight: 60.2 height: 1.75
说明:
1.在 (child.*pPrint)和 (pAdult->*pPrint)两边的括号是语法所强制要求的。
2.指向外部原函数(全局函数)的指针和指向类成员函数的指针是有很大区别的,类成员函数指针必须指向被调函数的宿主对象。因此,除了要有成员指针外还要有合法对象或对象指针。
当然,还可以把成员函数指针pPrint的定义放在Person类中,这时指针pPrint为Person类的一个成员。如下:
class Person{private:int age;float weight;float height; public:typedef void (Person::*PrintFunc)();PrintFunc pPrint; public:Person(int _age, float _weight, float _heigth){age = _age;weight = _weight;height = _heigth;pPrint = &Person::PrintPersonInfo;} void PrintPersonInfo(){cout << "age: " << age << " weight: " << weight << " height: " << height << endl;}}; void testMemberFuncPtr(){Person child(2, 15.2, 0.45);(child.*child.pPrint)();//把pPrint指针邦定到child对象 Person adult(22, 60.2, 1.75);Person* pAdult = &adult;(pAdult->*pAdult->pPrint)();//把pPrint指针邦定到pAdult指向的对象(即adult对象)}
静态成员函数的指针
静态成员函数指针的定义与一般的全局函数一样:
Return_Type (pointer_name) (Argument_List);
例如:
class Person{private:int age;float weight;float height; public:Person(int _age, float _weight, float _heigth){age = _age;weight = _weight;height = _heigth;} void PrintPersonInfo(){cout << "age: " << age << " weight: " << weight << " height: " << height << endl;} static void Sleep(){cout << "Sleep..." << endl;}}; //非静态成员函数的指针typedef void (Person::*PrintFunc)();PrintFunc pPrint = &Person::PrintPersonInfo; //静态成员函数的指针typedef void(*StaticMemberFuncType)();StaticMemberFuncType pSleep = &Person::Sleep;//可以为&Person::Sleep,也可以为 void testMemberFuncPtr(){Person child(2, 15.2, 0.45);(child.*pPrint)();//非静态成员函数的指针pPrint要邦定到类的对象child上 pSleep();//静态成员函数的指针不需要邦定,直接调用//(child.*pSleep)();//expression must have point-to-memeber type}
说明:
一个静态成员函数没有 this 指针。除了它和其它的类成员共享命名空间(类名,如此例中为Person)之外,它和常规全局函数是一样的。所以,静态成员函数不是类的一部分,成员函数指针的语法对静态成员函数指针并不成立。
成员函数为虚函数
对于nonstatic member function (非静态成员函数)取地址,获得该函数在内存中的实际地址
对于virtual function(虚函数),其地址在编译时期是未知的,所以对于virtual member function(虚成员函数)取其地址,所能获得的只是一个索引值。
例:
#include "stdafx.h"#include <iostream>#include <stdio.h>#include <string> using namespace std; class Person{private:int age;float weight;float height; public:Person(int _age, float _weight, float _heigth){age = _age;weight = _weight;height = _heigth;} virtual void EatFood(string foodName) = 0; virtual void Play(){cout << "Playing..." << endl;} void PrintPersonInfo(){cout << "age: " << age << " weight: " << weight << " height: " << height << endl;} static void Sleep(){cout << "Sleep..." << endl;}}; class Student : public Person{private:int studentId; public:Student(int _age, float _weight, float _heigth, int _studentId) : Person(_age, _weight, _heigth){studentId = _studentId;} virtual void EatFood(string foodName){cout << "Eating " << foodName << "..." << endl;} virtual void Play(){cout << "Playing games..." << endl;} void PrintPersonInfo(){Person::PrintPersonInfo();cout << studentId << endl;}}; void testMemberFuncPtr(){printf("Person::PrintPersonInfo: %p\n", &Person::PrintPersonInfo);printf("Person::EatFood: %p\n", &Person::EatFood);printf("Person::Play: %p\n", &Person::Play); printf("Student::PrintPersonInfo: %p\n", &Student::PrintPersonInfo);printf("Student::EatFood: %p\n", &Student::EatFood);printf("Student::Play: %p\n", &Student::Play); typedef void (Person::*PrintFuncType)();typedef void (Person::*VirtualFuncType)(string);PrintFuncType pPlay = &Person::Play;VirtualFuncType pEatFood = &Person::EatFood;Student student(18, 60.0, 1.76, 1);(student.*pPlay)();//调的是子类Student的Play方法(student.*pEatFood)("vegetable");//调的是子类Student的EatFood方法}
结果:
Person::PrintPersonInfo: 01181190
Person::EatFood: 01181294
Person::Play: 011812E9
Student::PrintPersonInfo: 01181398
Student::EatFood: 01181294
Student::Play: 011812E9
Playing games...
Eating vegetable...
当成员函数是虚函数的时候,成员函数能够具有多态性并且可用父类的成员函数指针调用子类的方法。“一个指向虚成员的指针能在不同地址空间之间传递,只要二者使用的对象布局一样” (此话来自C++老爸 Bjarne Stroustrup 的 《C++程序设计语言》 )。 当函数是虚函数的时候,编译器会生成虚函数表,来保存虚函数的地址。这是和非虚函数之间的最大不同,因此,运行时的行为也是不同的。
- 类成员函数的指针
- 类的成员函数指针
- 类的成员函数指针
- 类的成员函数指针
- 类成员函数的指针
- 成员函数的指针
- 成员函数的指针
- 类的成员变量偏移指针和成员函数指针
- 类的成员变量偏移指针和成员函数指针 .
- 类的数据成员指针和成员函数指针
- 函数指针调用类的成员函数
- 指向 类成员函数 的 函数指针
- 类成员函数的函数指针
- 类成员函数的函数指针
- 函数指针调用类的成员函数
- 带成员函数指针的成员函数
- 类的普通成员函数的指针
- 类的普通成员函数的指针
- 自定义带图片按钮的实现。
- LeetCode OJ 之 Length of Last Word(求最后一个单词的长度)
- 第11周项目6-回文、素数-回文数
- 负值之美:负margin在页面布局中的应用
- 和为n连续正数序列 【微软面试100题 第五十一题】
- 类的成员函数的指针
- C#中的特性 和 通过反射获取属性上的特性
- 学习总结与未来规划
- Native code library failed to load: ensure the appropriate library (opl124.dll/.so) is in your path.
- margin负值原理
- 关于内容泄露问题
- poj1088滑雪(dfs+记忆化搜索、备忘录)
- 栈与队列实验
- remove()与 empty()的区别