1

我正在做一个相当复杂的项目,如果你愿意的话,一个自定义加密例程(只是为了好玩)我在设计我的代码布局时遇到了这个问题。

我有许多我希望能够按索引调用的函数。具体来说,我需要能够为加密过程随机调用一个,然后通过解密过程中的特定索引来解决它。

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

-尼古拉斯

4

8 回答 8

5

函数数组有什么问题?

您需要按索引调用函数。因此,它们必须以某种方式放入某种“可按索引索引”的结构中。数组可能是最适合这种需求的最简单的结构。

示例(从我的脑海中输入,可能无法编译):

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

上述方法中的“丑陋”或“难以维护”是什么?

于 2008-09-24T07:52:52.773 回答
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作为函数名称。

于 2008-09-24T08:00:09.760 回答
0

定义了 operator() 方法的对象可以像函数一样工作,但通常更易于使用。

于 2008-09-24T07:50:35.460 回答
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 };
  • 函数声明和定义在单独的文件中 - 编译时间没问题。
  • 函数分组在一个单独的文件中,仅依赖于声明
于 2008-09-24T08:05:11.137 回答
0

您可以查看Boost.Signals 库。我相信它有能力使用索引来调用它的注册函数。

于 2008-09-24T08:15:13.997 回答
0

试试 Loki::Functor 类。CodeProject.com上的更多信息

于 2008-09-24T08:30:07.037 回答
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
于 2008-09-24T09:39:00.647 回答
0

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

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

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

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

int iFuncIdx = 0;
int iRetCode = functinPointer[iFuncIdx++]();
于 2010-06-24T15:58:14.460 回答