C ++创建指向标头内所有公共静态成员函数的指针数组,然后使用它

Posted

技术标签:

【中文标题】C ++创建指向标头内所有公共静态成员函数的指针数组,然后使用它【英文标题】:C++ Create pointer array to all public static member functions inside header and then use it 【发布时间】:2014-05-02 13:34:38 【问题描述】:

[Ubuntu 13.10]

我正在创建一个包含一堆回调函数的类。在我的主程序中,我将这些回调分配给各个节点。我希望能够在循环中执行此操作,因此我尝试在具有其成员函数的所有地址的头类(无 .cpp)中创建一个静态指针数组。

我似乎无法找出执行此操作的语法。

1) 下面是我的标题定义的类。我是否以正确的方式初始化 cbPointer?

#include "std_msgs/String.h"

typedef void (*FunctionPointer)(const std_msgs::String_<std::allocator<void> >::ConstPtr &);

class myCallbacks 

public:


    static void cbEvent1(const std_msgs::String::ConstPtr& msg) 
            std::cout << "I heard: " << msg->data.c_str() << std::endl;
    

    static void cbEvent2(const std_msgs::String::ConstPtr& msg) 
            std::cout << "I heard: " << msg->data.c_str() << std::endl;
    

    constexpr static const FunctionPointer cbPointer[2] = &myCallbacks::cbEvent1, &myCallbacks::cbEvent2;

;

然后在我的主程序中,我像这样分配回调:

for (int j=0; j<NO_CALLBACKS; j++) 
    subList[j] = (sNode[j])->subscribe(myCallbacks::cbPointer[j]);

subscribe 方法具有以下签名:

template<class M , class T >
subscribe (void(T::*fp)(M))

但我收到 链接 错误:undefined reference to myCallbacks::cbPointer。我尝试了subList[j] = (sNode[j])-&gt;subscribe(myCallbacks::cbPointer[j]); 的各种变体,但似乎没有任何效果。

有人可以帮助我正确的语法吗? (另外,是否可以在不拼写每个函数名称的情况下在标题中创建数组?)

【问题讨论】:

除了声明之外,您是否在 .cpp 文件中定义了 cbPointer 不,都是通过头文件来做的。 在头文件中定义数据是个坏主意,因为它可能违反One Definition Rule。 【参考方案1】:

我已经想出了如何完成它:

#ifndef MYCALLBACKS_H
#define MYCALLBACKS_H

#include "std_msgs/String.h"

typedef void (*FunctionPointer)(const std_msgs::String_<std::allocator<void> >::ConstPtr &);

class myCallbacks 

public:


    static void cbEvent1(const std_msgs::String::ConstPtr& msg) 
            std::cout << "I heard: " << msg->data.c_str() << std::endl;
    

    static void cbEvent2(const std_msgs::String::ConstPtr& msg) 
            std::cout << "I heard: " << msg->data.c_str() << std::endl;
    

    static FunctionPointer cbPointer[];


FunctionPointer myCallbacks::cbPointer[] = &myCallbacks::cbEvent1, &myCallbacks::cbEvent2;

#endif

现在我可以使用myCallbacks::cbPointer[x]来引用成员函数的地址了。

【讨论】:

通过在标题中定义数组,您可能会违反One Definition Rule。如果您的头文件曾经包含在多个翻译单元中(即,由多个 .cpp 文件),那么每个翻译单元都会获得数组的副本,从而违反 ODR。正确的做法是为静态数据成员定义一个单独的 .cpp 文件,并且只在头文件中保留声明。是的,它有点冗长,但以后会让你头疼。 是的,我没有在代码中包含#ifndef指令,我会添加它。 @SchighSchagh,IC。这会导致错误,还是只会使可执行文件变大? (此标头用作较大对象的子对象,不会单独包含在其他任何内容中。)请问您的 cmets 吗?

以上是关于C ++创建指向标头内所有公共静态成员函数的指针数组,然后使用它的主要内容,如果未能解决你的问题,请参考以下文章

在另一个类c ++中调用成员函数

如果它被定义为c ++类中的成员函数,我得到了“非标准语法;使用'&'创建指向成员的指针“[复制]

类内定义线程的回调函数问题

返回指向函数静态数据的指针是不是合适?

指向具有私有构造函数的类的类成员的指针

C++ Visual Studio 非标准语法使用 '&' 创建指向成员的指针