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])->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 ++创建指向标头内所有公共静态成员函数的指针数组,然后使用它的主要内容,如果未能解决你的问题,请参考以下文章