我想要一个可维护的数组/可能的功能/行为列表,每个代表另一种操作模式,我想改变'模式'只需更改存储指向右侧函数的变量即可。
通过研究我发现事实,功能指针有点臭,但我想知道是否
答:无论如何,在我的用例中使用它们是可以的
B
有更好/专业的选择。
一些伪代码显示我喜欢的使用方式:
// store references to the modes and an information about the active mode
void * allModePointers[3];
int modeNumber = 2;
// call the active mode
(*allModePointers[modeNumber])();
答案 0 :(得分:1)
void*
对它所接受的类型非常自由。通过使用它,您放弃编译时类型检查。没有typedef void* ModeFunctionPtr
,也很难理解。
要获取类型检查并避免指针转换,您需要一个正确声明的函数指针数组,如void(*allModePointers[3])()
(由cdecl.org验证)。这只适用于功能签名匹配的情况,如果他们没有,则表示您做错了。
最后,我建议std::function
,它是可调用对象的包装器。它具有能够接受lambda表达式的优点,并且如果您有一天发现静态函数不够,则可以与std
等其他std::bind
函数一起使用。
答案 1 :(得分:0)
简答:使用C ++时,实现库中不存在的行为的最专业方法是使用类。
具体建议:如果我正确理解您的意图,您希望建模类似终端的模型(即根据命令执行任务)。我要做的是创建一个只有函数的类(我之前已经完成了这个以模拟计算器),如果你需要它们可能会抛出一些静态常量。其中一个函数是一个控制函数,它只接受命令并根据该命令调用其他函数之一,然后返回答案。把它扔进.h,用Doxygen和瞧瞧它看起来很整洁!你有可维护的行为列表。我将使用我的计算器示例演示如下。我做的那个是做矢量计算,但我会做一个只添加和正方形的简单。
/* doxygen comments */
/* include guards, includes, etc, etc */
class Calculator{
public:
/* static constants if needed (i.e. pi, e, ...) */
/* constructor, destructor, getters if you want to make the
constants private */
/* doxygen comments */
double run( int function_id, double x, double y ){
switch( function_id ){
case 0: return add( x, y );
case 1: return square( x );
default: return x; //why not?
}
}
private:
/* doxygen comments */
inline double square( double x ) { return x*x; }
/* doxygen comments */
inline double add( double x, double y ) { return x+y; }
};
虽然这个例子和我的有点不同,因为我实际上只是公开了所有的功能,并且自己从main中调用它们。无论如何,你得到了要点,但也可能是内存成本较低的方式。