如何理解C++成员指针函数表?

发布于 2022-09-12 00:45:36 字数 2090 浏览 32 评论 0

下面的程序(已经编译通过)是C++ Primer 5th 第19章(19.4.2 成员函数指针 第743页)中的一个例程:

/*1 */#include <iostream>
/*2 */#include<vector>
/*3 */#include<algorithm>
/*4 */#include<numeric>
/*5 */#include<map>
/*6 */#include<string>
/*7 */#include<functional>
/*8 */ 
/*9 */using namespace std;
/*10*/ 
/*11*/class Screen {
/*12*/public:
/*13*/    Screen& home() { return *this; }
/*14*/    Screen& forward() { return *this; }
/*15*/    Screen& back() { return *this; }
/*16*/    Screen& up() { return *this; }
/*17*/    Screen& down() { return *this; }
/*18*/    using Action1 = Screen & (Screen::*)();
/*19*/    enum  Directions { HOME, FORWARD, BACK, UP,
/*20*/                       DOWN};
/*21*/     Screen& move(Directions cm)
/*22*/       {
/*23*/           //运行this对象中索引值为cm的元素
/*24*/           return(this->*(Menu[cm]))();
/*25*/       }
/*26*/private:
/*27*/    static Action1 Menu[];
/*28*/};
/*29*/ 
/*30*/Screen::Action1 Screen::Menu[] = {  &Screen::home,
/*31*/                                    &Screen::forward,
/*32*/                                    &Screen::back,
/*33*/                                    &Screen::up,    
/*34*/                                    &Screen::down,
/*35*/                                    };
/*36*/int main()
/*37*/{
/*38*/    Screen myScreen, * pScreen = &myScreen;
/*39*/    myScreen.move(Screen::HOME);   
/*40*/    cout << "Ban Ji Tino\n";
/*41*/}

不理解的地方:

  1. 第30行代码 “ Screen::Action1 Screen::Menu[] ”这种用法 应该 去怎么理解? Action1类型的数组?
  2. 成员函数指针调用得时候 为什么在类内部还需要说明this->*
    而且 我在测试用法的时候在外部 甚至需要auto fp= (pScreen->*(pScreen->Menu[]))(); 这么复杂的形式。我看书里说是因为要指明调用的是 成员指针 。但是逻辑上我有点理解不通。
  3. 如果实例调用myScreen.move(Screen::HOME)时,是隐式的把 Screen::HOME 转换为值为1的int类型了么?
  4. 第27行代码static Action1 Menu[]; 为什么要使用static?
  5. 如果把Screen类和函数表的定义和初始化部分(代码第30到第35行的内容)放到另外一个pdd.cpp文件,并且在主文件#include"pdd.cpp" 编译会提示重复定义。只有把函数表的定义和初始化部分放到住文件中才能编译通过。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最丧也最甜 2022-09-19 00:45:36
  1. 对,Menu是个数组,数组元素的类型是Action1。
  2. 通过成员指针访问成员的语法就是这样。这里用到的操作符是->*,这个操作符需要两个操作数,左侧指明要访问谁的成员,右侧指明访问哪个成员。
  3. Screen::Direction::Home的值是0。语法上Screen::HOME可以直接参与built-in下标运算,不清楚有没有被转换。
  4. 设计上Screen的实例可以共享这个成员,这种情况下声明为static可节省内存。
  5. pdd和主文件都会被编译成目标文件,在这两个目标文件中都有Screen::Menu的定义(类外声明并初始化的那行),这违背了one definition rule。这个错误会在链接时被检查出来。
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文