C++指向类成员/函数的指针

C++扩展了指针在类中的使用,使其可以指向类成员,这种行为是类层面的,而不是对象层面的。

指向类成员/函数的指针的本质并不是取地址.而是利用了对象地址的偏移量

我们创建了一个类,假设我们要使用指针指向类中的成员


 
 
  1. class Student {
  2. public:
  3. Student( string n, int nu):name{n},num{nu}{}
  4. void dis(int idx) {
  5. cout << idx << " " << name << " " << num << endl;
  6. }
  7. public:
  8. string name;
  9. int num;
  10. };

我们可以这么做:string * ss1 = &s1.name;但是这样做是没有意义的,这样会破坏类的封装,这样这个类就没有存在意义了

C++提供了指向类成员的指针: 变量类型 类名::*pointer = &类名::变量名;

在这个类中,我们可以这么使用

string Student::*pstr1 = &Student::name;
 
 

想要具体使用指针,我们还是要使用类的对象去调用,这是一种新的运算符,叫做指向类的指针

对象.*成员对象指针

指向对象指针->*成员对象指针

在本案例中可以这么使用:


 
 
  1. Student s1("zhangsan", 100);
  2. Student* ps1 = &s1;
  3. Student s2("zhangsan", 100);
  4. Student* ps2 = &s2;
  5. string Student::*pstr1 = &Student::name;
  6. cout << s1.*pstr1 << endl; //不同的对象可以调用同一个指针
  7. cout << ps1->*pstr1 << endl;
  8. cout << s2.*pstr1 << endl;
  9. cout << ps2->*pstr1 << endl;

指向类成员的指针用的不多,一般用的较多的是指向类成员函数的指针

返回值类型 (类名::*ptr)(函数参数) = &类名:: 成员函数

void (Student::*pdis)(int) = &Student::dis;
 
 

调用方法与成员对象指针类似: 因为优先级问题要加上括号


 
 
  1. (s1.*pdis)( 10);
  2. (ps1->*pdis)( 20);

以下提供两个成员函数指针的案例


 
 
  1. #include <iostream>
  2. using namespace std;
  3. struct Point
  4. {
  5. int add(int x, int y) {
  6. return x + y;
  7. }
  8. int minNus(int x, int y) {
  9. return x - y;
  10. }
  11. int multi(int x, int y) {
  12. return x * y;
  13. }
  14. int div(int x, int y) {
  15. return x / y;
  16. }
  17. };
  18. //提供公共接口
  19. int oper(Point& p, int(Point::*pp)(int, int), int x, int y) { //指向函数成员的指针
  20. return (p.*pp)(x, y);
  21. }
  22. typedef int(Point::*PF)(int, int);
  23. int main() {
  24. Point p;
  25. PF padd = &Point::add;
  26. cout << oper(p, padd, 10, 20) << endl;
  27. padd = &Point::minNus;
  28. cout << oper(p, padd, 500, 20) << endl;
  29. system( "PAUSE");
  30. }

在这个案例中,我们使用成员函数指针实现了一个公共接口


 
 
  1. #include <iostream>
  2. using namespace std;
  3. class Game {
  4. public:
  5. Game() {
  6. PSkill[ 0] = &Game::SkillOne;
  7. PSkill[ 1] = &Game::SkillTwo;
  8. PSkill[ 2] = &Game::SkillThree;
  9. PSkill[ 3] = &Game::SkillFour;
  10. }
  11. void select(int index) {
  12. if (index >= 0 && index <= 3) {
  13. ( this->*PSkill[index])();
  14. }
  15. }
  16. private:
  17. void SkillOne() { cout << "Use skill one.." << endl; }
  18. void SkillTwo() { cout << "Use skill Two.." << endl; }
  19. void SkillThree() { cout << "Use skill Three.." << endl; }
  20. void SkillFour() { cout << "Use skill Four.." << endl; }
  21. enum {
  22. NC = 4 //技能数量
  23. };
  24. void (Game::*PSkill[NC])();
  25. };
  26. int main() {
  27. Game newOne;
  28. newOne.select( 2);
  29. newOne.select( 0);
  30. newOne.select( 3);
  31. system( "PAUSE");
  32. }

这个案例中,假设我们不想让外界知道类内部的函数名,我们可以是用指向成员函数的指针数组将它们封装起来,加强了隐蔽性

  •                     <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="{&quot;mod&quot;:&quot;popu_824&quot;}"><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="{&quot;mod&quot;:&quot;1582594662_002&quot;}"><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="{&quot;mod&quot;:&quot;popu_379&quot;}" 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="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值