版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alex1997222/article/details/81983073
C++扩展了指针在类中的使用,使其可以指向类成员,这种行为是类层面的,而不是对象层面的。
指向类成员/函数的指针的本质并不是取地址.而是利用了对象地址的偏移量
我们创建了一个类,假设我们要使用指针指向类中的成员
class Student {
public:
Student(string n,int nu):name{n},num{nu}{}
void dis(int idx) {
cout << idx << " " << name << " " << num << endl;
}
public:
string name;
int num;
};
我们可以这么做:string * ss1 = &s1.name;但是这样做是没有意义的,这样会破坏类的封装,这样这个类就没有存在意义了
C++提供了指向类成员的指针: 变量类型 类名::*pointer = &类名::变量名;
在这个类中,我们可以这么使用
string Student::*pstr1 = &Student::name;
想要具体使用指针,我们还是要使用类的对象去调用,这是一种新的运算符,叫做指向类的指针
对象.*成员对象指针
指向对象指针->*成员对象指针
在本案例中可以这么使用:
Student s1("zhangsan", 100);
Student* ps1 = &s1;
Student s2("zhangsan", 100);
Student* ps2 = &s2;
string Student::*pstr1 = &Student::name;
cout << s1.*pstr1 << endl; //不同的对象可以调用同一个指针
cout << ps1->*pstr1 << endl;
cout << s2.*pstr1 << endl;
cout << ps2->*pstr1 << endl;
指向类成员的指针用的不多,一般用的较多的是指向类成员函数的指针
返回值类型 (类名::*ptr)(函数参数) = &类名:: 成员函数
void (Student::*pdis)(int) = &Student::dis;
调用方法与成员对象指针类似: 因为优先级问题要加上括号
(s1.*pdis)(10);
(ps1->*pdis)(20);
以下提供两个成员函数指针的案例
#include <iostream>
using namespace std;
struct Point
{
int add(int x, int y) {
return x + y;
}
int minNus(int x, int y) {
return x - y;
}
int multi(int x, int y) {
return x * y;
}
int div(int x, int y) {
return x / y;
}
};
//提供公共接口
int oper(Point& p, int(Point::*pp)(int, int), int x, int y) { //指向函数成员的指针
return (p.*pp)(x, y);
}
typedef int(Point::*PF)(int, int);
int main() {
Point p;
PF padd = &Point::add;
cout << oper(p, padd, 10, 20) << endl;
padd = &Point::minNus;
cout << oper(p, padd, 500, 20) << endl;
system("PAUSE");
}
在这个案例中,我们使用成员函数指针实现了一个公共接口
#include <iostream>
using namespace std;
class Game {
public:
Game() {
PSkill[0] = &Game::SkillOne;
PSkill[1] = &Game::SkillTwo;
PSkill[2] = &Game::SkillThree;
PSkill[3] = &Game::SkillFour;
}
void select(int index) {
if (index >= 0 && index <= 3) {
(this->*PSkill[index])();
}
}
private:
void SkillOne() { cout << "Use skill one.." << endl; }
void SkillTwo() { cout << "Use skill Two.." << endl; }
void SkillThree() { cout << "Use skill Three.." << endl; }
void SkillFour() { cout << "Use skill Four.." << endl; }
enum {
NC = 4 //技能数量
};
void (Game::*PSkill[NC])();
};
int main() {
Game newOne;
newOne.select(2);
newOne.select(0);
newOne.select(3);
system("PAUSE");
}
这个案例中,假设我们不想让外界知道类内部的函数名,我们可以是用指向成员函数的指针数组将它们封装起来,加强了隐蔽性