指向類成員/函式的指標
阿新 • • 發佈:2019-01-13
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");
}
這個案例中,假設我們不想讓外界知道類內部的函式名,我們可以是用指向成員函式的指標陣列將它們封裝起來,加強了隱蔽性