2008-09-24 82 views
1

我正在开发一个相当复杂的项目,如果您愿意(只是为了好玩)定制加密程序,并且在设计我的代码布局时遇到了这个问题。C++函数列表

我有很多功能,我希望能够通过索引来调用。具体来说,我需要能够随机调用一个用于加密过程,但是随后通过解密过程中的特定索引解决该问题。

我正在考虑一个经典的函数数组,但我主要关心的是函数数组维护会很棘手,而且有点难看。 (目标是将每个函数对都放在一个单独的文件中,以减少编译时间并使代码更易于管理。)有没有人有更优雅的C++解决方案作为函数数组的替代方案?速度不是真正的问题,我更担心可维护性。

-Nicholas

回答

2

你可以写类似:

class EncryptionFunction 
{ 
public: 
    virtual Foo Run(Bar input) = 0; 
    virtual ~MyFunction() {} 
}; 

class SomeSpecificEncryptionFunction : public EncryptionFunction 
{ 
    // override the Run function 
}; 

// ... 

std::vector<EncryptionFunction*> functions; 

// ... 

functions[2]->Run(data); 

你可以使用operator()代替Run作为函数名,如果你喜欢。

0

具有限定可充当很像一个函数,但是大致更好一起工作的操作者()方法的对象。

5

函数数组有什么问题?

您需要通过索引调用函数。所以他们必须被放入一些“按指数索引”结构莫名其妙。数组可能是适合这种需求的最简单的结构。

例(打字了我的头,可能无法进行编译):

struct FunctionPair { 
    EncodeFunction encode; 
    DecodeFunction decode; 
}; 
FunctionPair g_Functions[] = { 
    { MyEncode1, MyDecode1 }, 
    { MySuperEncode, MySuperDecode }, 
    { MyTurboEncode, MyTurboDecode }, 
}; 

什么是在上面的办法“丑”或“难以维持”?

0

多态可以做到这一点:你可以按照策略模式,考虑每个策略来实现你的一个函数(或它们的一对)。

然后创建一个策略向量,并使用这个而不是函数列表。

但坦率地说,我没有看到函数数组的问题;您可以轻松创建一个typedef来简化可读性。有效地,当使用策略模式时,您将得到完全相同的文件结构。

// functiontype.h 
typedef bool (*forwardfunction)(double*, double*); 

// f1.h 
#include "functiontype.h" 
bool f1(double*, double*); 

// f1.c 
#include "functiontype.h" 
#include "f1.h" 
bool f1(double* p1, double* p2) { return false; } 


// functioncontainer.c  
#include "functiontype.h" 
#include "f1.h" 
#include "f2.h" 
#include "f3.h" 

forwardfunction my_functions[] = { f1, f2, f3 }; 
  • 函数声明和定义在不同的文件 - 编译时间是确定的。
  • 的功能分组是在一个单独的文件,具有依赖性的声明仅
0

更多信息如果您在boost::signals库望去,你会看到一个例子很不错的,这是非常优雅:
假设你有4种功能,如:

void print_sum(float x, float y) 
{ 
    std::cout << "The sum is " << x+y << std::endl; 
} 

void print_product(float x, float y) 
{ 
    std::cout << "The product is " << x*y << std::endl; 
} 

void print_difference(float x, float y) 
{ 
    std::cout << "The difference is " << x-y << std::endl; 
} 

void print_quotient(float x, float y) 
{ 
    std::cout << "The quotient is " << x/y << std::endl; 
} 

然后,如果你想叫他们一个优雅的方式尝试:

boost::signal<void (float, float)> sig; 

sig.connect(&print_sum); 
sig.connect(&print_product); 
sig.connect(&print_difference); 
sig.connect(&print_quotient); 

sig(5, 3); 

,输出是:

The sum is 8 
The product is 15 
The difference is 2 
The quotient is 1.66667 
+0

建议:为代码示例使用 '代码示例' 格式。这是答案编辑器中的“零和”按钮。 – jwfearn 2008-09-24 15:39:05

0

您需要使用一个函数指针数组。唯一的问题是所有的函数都必须具有基本相同的原型,只有函数的名称和传入的参数名称可以有所不同。返回类型和参数类型(以及参数和顺序的数量)必须相同。

int Proto1(void); 
int Proto2(void); 
int Proto3(void); 

int (*functinPointer[3])(void) = 
{ 
    Proto1, 
    Proto2, 
    Proto3 
}; 

然后,你可以做这样的事情:

int iFuncIdx = 0; 
int iRetCode = functinPointer[iFuncIdx++]();