C++调用静态成员函数指针

Posted

技术标签:

【中文标题】C++调用静态成员函数指针【英文标题】:C++ calling static member function pointer 【发布时间】:2015-06-30 20:45:47 【问题描述】:

我对 C++ 非常陌生,并且在执行静态成员函数指针时遇到了一些问题运气不好!

这是头文件和源文件的代码 sn-p 以及我得到的错误:Actions.h

class Actions
private:
    int actionId;
    int stateId;
    int eventId;
public:
    typedef string (Actions::*functionPtr)(int previousState, int currentState, int eventId);
    static functionPtr _ptrAction1;
    int doAction(int previousState, int currentState, int eventId);
    string function1(int previousState, int currentState, int eventId);
;

Actions.c:

#include "stdafx.h"
#include "Actions.h"
Actions::Actions(int actionId, int stateId, int eventId)
    this->actionId = actionId;
    this->stateId = stateId;
    this->eventId = eventId;
    _ptrAction1 = &Actions::function1;


int doAction(int actionId, int previousState, int currentState, int eventId)
int functionId = 0;
string message;

switch(actionId)
   case 1:
       message = (*_ptrAction1)(previousState, currentState, eventId);
       break;
   default:
       break;
   


string Actions::function1(int previousState, int currentState, int eventId)
    return "this is an example for now";

我收到的错误在 Actions.c 在线

message = (*_ptrAction1)(previousState, currentState, eventId);

错误如下:

1>Actions.cpp(37):错误 C2065:'_ptrAction1':未声明的标识符

我想也许我引用它不正确,所以我将上面的行更改为如下:

message = (*Actions::_ptrAction1)(previousState, currentState, eventId);

但现在我收到一个不同的错误:

Actions.cpp(37):错误 C2064:术语不计算为采用 3 个参数的函数

作为参考,我已阅读C++ calling static function pointer,但这与我遇到的问题不同。我真的希望您能提供帮助,感谢您抽出宝贵的时间,非常感谢!

【问题讨论】:

这是完整的代码吗?你不实现function1,只定义它。 对不起,这不是完整的代码,只是一个片段,我将包含 function1 以供参考。 【参考方案1】:

ptrAction1 是指向对象方法的静态指针。 function1 是指针指向的方法,因此您必须在对象上下文中调用它。

假设你想在当前对象上调用它,那么*this.*_ptrAction1就是在方法中调用它的方式。

您的doAction 函数没有使用任何Actions 实例,因此您无法调用该方法...将doAction(4 params) 定义为类的方法或将实例作为参数传递。

【讨论】:

*.* 的相对优先级相当令人惊讶,我差点误编辑添加了括号。 *this.* .. 或this->* 非常感谢Jean-Baptiste 的简明解释!我没有意识到我已经将 Actions:: 离开了 doAction 方法(我现在觉得有点傻)!【参考方案2】:

您发布的代码存在一些问题:

首先,您需要正确声明您的 Actions::doAction 方法以匹配您的其他 doAction 的签名(反之亦然)。

接下来,由于您已将 _ptrAction1 声明为静态成员,因此您需要重新声明类外部的链接(否则您将收到未定义的引用错误)。

之后,你可以这样调用它:(this->*_ptrAction1)(...),当你在 Actions 上下文中时(也就是说,你可以在 Actions 的另一个成员函数中调用 this->*)。

原因是你需要一个对象实例来调用pointer-to-member function,所以如果你有一个Actions 的有效对象,你就不需要明确地需要this(参见主函数):

#include <iostream>
#include <string>

class Actions
private:
    int actionId;
    int stateId;
    int eventId;
public:
    typedef std::string (Actions::*functionPtr)(int previousState, int currentState, int eventId);
    static functionPtr _ptrAction1;

    Actions(int actionId, int stateId, int eventId)
    
        this->actionId = actionId;
        this->stateId = stateId;
        this->eventId = eventId;
        Actions::_ptrAction1 = &Actions::function1;
    
    int doAction(int act, int previousState, int currentState, int eventId);
    std::string function1(int previousState, int currentState, int eventId);
;

// linker
Actions::functionPtr Actions::_ptrAction1;

std::string Actions::function1(int previousState, int currentState, int eventId)
    return "this is an example for now";


int Actions::doAction(int act, int previousState, int currentState, int eventId)

    int functionId = 0;
    std::string message;

    switch(act)
       case 1:
           message = (this->*_ptrAction1)(previousState, currentState, eventId);
           break;
       default:
           break;
       


int main(int argc, char* argv[])

    Actions* act = new Actions(1,2,3);
    // have to say Actions::_ptrAction1 since it's a static member, but
    // we still need a valid Actions object to act on (for the hidden this)
    std::cout << (act->*Actions::_ptrAction1)(3,2,1) << std::endl;
    delete act;
    return 0;

【讨论】:

谢谢 txtechhelp 非常有帮助,尤其是您对重新声明和 * 优先级的解释。我会根据您的建议修改我的代码,恐怕我没有代表来投票,否则我会这样做! :) @tfstorm,不用担心!很高兴我能帮忙:)

以上是关于C++调用静态成员函数指针的主要内容,如果未能解决你的问题,请参考以下文章

C++ CreateThread函数如何传递this指针作为参数

指向任何类类型的非静态成员函数的 C++ 函数指针

c++复习篇

如何从静态成员函数调用指向成员函数的指针?

C++类和对象(this指针6个默认成员函数const成员)

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合