概述
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");
-
}
这个案例中,假设我们不想让外界知道类内部的函数名,我们可以是用指向成员函数的指针数组将它们封装起来,加强了隐蔽性
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#csdnc-thumbsup"></use> </svg><span class="name">点赞</span> <span class="count">2</span> </a></li> <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-Collection-G"></use> </svg><span class="name">收藏</span></a></li> <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{"mod":"1582594662_002"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-fenxiang"></use> </svg>分享</a></li> <!--打赏开始--> <!--打赏结束--> <li class="tool-item tool-more"> <a> <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg> </a> <ul class="more-box"> <li class="item"><a class="article-report">文章举报</a></li> </ul> </li> </ul> </div> </div> <div class="person-messagebox"> <div class="left-message"><a href="https://blog.csdn.net/alex1997222"> <img src="https://profile.csdnimg.cn/6/5/0/3_alex1997222" class="avatar_pic" username="alex1997222"> <img src="https://g.csdnimg.cn/static/user-reg-year/2x/4.png" class="user-years"> </a></div> <div class="middle-message"> <div class="title"><span class="tit"><a href="https://blog.csdn.net/alex1997222" data-report-click="{"mod":"popu_379"}" target="_blank">alex1997222</a></span> </div> <div class="text"><span>发布了317 篇原创文章</span> · <span>获赞 71</span> · <span>访问量 19万+</span></div> </div> <div class="right-message"> <a href="https://bbs.csdn.net/topics/395528712" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板 </a> <a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a> </div> </div> </div>
最后
以上就是柔弱故事为你收集整理的C++指向类成员/函数的指针的全部内容,希望文章能够帮你解决C++指向类成员/函数的指针所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复