C++ 功能列表

发布于 2024-07-06 04:41:11 字数 303 浏览 15 评论 0原文

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

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

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

-尼古拉斯

I'm working on a fairly complex project, a custom encryption routine if you will (just for fun) and I've run into this issue in designing my code layout.

I have a number of functions that I want to be able to call by index. Specifically, I need to be able to call one randomly for the encrypt process, but then address that by a specific index in the decrypt process.

I was considering a classic function array, but my main concern is that a function array would be tricky to maintain, and a little ugly. (The goal is to get each function pair in a separate file, to reduce compile times and make the code easier to manage.) Does anyone have a more elegant C++ solution as an alternative to a function array? Speed isn't really an issue, I'm more worried about maintainability.

-Nicholas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

杀お生予夺 2024-07-13 04:41:12

函数数组有什么问题?

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

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

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

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

What's wrong with function array?

You need to call functions by index. So they must be put into some "indexable by index" structure somehow. Array is probably the simplest structure that suits this need.

Example (typing out of my head, might not compile):

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

What is "ugly" or "hard to maintain" in the approach above?

猫瑾少女 2024-07-13 04:41:12

您可以编写如下内容:

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 作为函数名称。

You could write something like:

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);

You could use operator() instead of Run as the function name, if you prefer.

暖阳 2024-07-13 04:41:12

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

You could take a look at the Boost.Signals library. I believe it has the ability to call its registered functions using an index.

末蓝 2024-07-13 04:41:12

多态性可以解决这个问题:您可以遵循策略模式,考虑每种策略来实现您的一个函数(或其中一对)。

然后创建一个策略向量,并使用它代替函数列表。

但坦率地说,我不认为函数数组有问题; 您可以轻松创建 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 };
  • 函数声明和定义位于单独的文件中 - 编译时间没问题。
  • 函数分组位于单独的文件中,仅依赖于声明

Polymorphism could do the trick: you couldf follow the strategy pattern, considering each strategy to implement one of your functions (or a pair of them).

Then create a vector of strategies, and use this one instead of the function list.

But frankly, I don't see the problem with the function array; you can easily create a typedef to ease the readability. Effectifely, you will end up with exactly the same file structure when using the strategy pattern.

// 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 };
  • The function declaration and definitions are in separate files - compile time is ok.
  • The function grouping is in a separate file, having a dependency to the declarations only
最后的乘客 2024-07-13 04:41:12

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

An object with an operator() method defined can act a lot like a function but be generally nicer to work with.

城歌 2024-07-13 04:41:12

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

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

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

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

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

You need to use an array of function pointers. The only catch is that all the functions have to have basically the same prototype, only the name of the function and passed argument names can vary. The return type and argument types (as well as the number of arguments and order) must be identical.

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

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

Then you can do something like this:

int iFuncIdx = 0;
int iRetCode = functinPointer[iFuncIdx++]();
新人笑 2024-07-13 04:41:12

尝试 Loki::Functor 类。 更多信息请访问 CodeProject.com

Try Loki::Functor class. More info at CodeProject.com

追我者格杀勿论 2024-07-13 04:41:12

如果您查看 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

If you looked in boost::signals library, you'll see an example very nice, that is very elegant:

Suppose you have 4 functions like:

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;
}

Then if you want to call them in a elegant way try:

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);

And the output is:

The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文