Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 根据变量执行函数';s值-C++;_C++_Function Pointers - Fatal编程技术网

C++ 根据变量执行函数';s值-C++;

C++ 根据变量执行函数';s值-C++;,c++,function-pointers,C++,Function Pointers,我正在研究一种音译工具。我有两个模块lexer和translator。Lexer从输入文本中生成标记。根据当前选择的语言,我必须调用适当的翻译例程 我想出了两个办法来做这件事。第一个是创建一个名为base\u translator的基类,并提供每个translator都必须重写的虚拟方法(translate())。现在创建一个工厂translator\u工厂,并使用语言名称调用create()。此工厂将返回适当的实例 但这似乎过于工程化了。因此,我提出了另一种方法,其中我有一个结构,如下所示 s

我正在研究一种音译工具。我有两个模块lexer和translator。Lexer从输入文本中生成标记。根据当前选择的语言,我必须调用适当的翻译例程

我想出了两个办法来做这件事。第一个是创建一个名为
base\u translator
的基类,并提供每个translator都必须重写的虚拟方法(
translate()
)。现在创建一个工厂
translator\u工厂
,并使用语言名称调用
create()
。此工厂将返回适当的实例

但这似乎过于工程化了。因此,我提出了另一种方法,其中我有一个结构,如下所示

struct translator
{
    const char* name;
    void (*fp)();
};
它只保留一个语言名和一个可以处理它的函数指针。用法将是

static translator translators[] = {
    {"first", first},
    {"second", second}
};
const char* language = /* */; 
for(int i = 0; i < 2; i++) {
    translator *t = translators + i;
    if(strcmp(t->name, language) == 0) {
        t->fp();
        break;
    }
}
static translator[]={
{“第一”,第一},
{“第二”,第二}
};
常量字符*语言=/**/;
对于(int i=0;i<2;i++){
翻译人员*t=翻译人员+i;
if(strcmp(t->名称,语言)==0){
t->fp();
打破
}
}
这种方法非常简单,易于维护。但我想知道,这是解决问题的最好办法吗?你有什么好的建议吗


任何帮助都会很好。

这是抽象类和虚拟函数的典型用例。我不明白你为什么认为这是“过度工程”。。。。欧欧欧


关键是要定义一个契约,这样您的代码就可以很容易地扩展,“主代码”就不必担心实际的实现细节。

您的第二种方法在两个项目上看起来可能更简单(对我来说不是…),但从长远来看,它更容易出错,也更难维护。无论何时添加新语言,都需要在至少两个位置触碰代码。(请相信我:即使您目前似乎不太可能这样做,但这几乎不可避免地会发生……)如果您忘记更新循环边界,那么代码中就有一个无声的bug。此外,此实现比多态实现慢得多:您需要在每次调用之前迭代数组并比较字符串(而不是在vtable中查找指针)

我肯定会使用工厂。除了上述优点外,它还是一种众所周知的设计模式,更易于理解。因此,为了维护代码而跟随您的人不会那么诅咒您;-)


更新:工厂也可以返回函数指针。在这种情况下,我仍然会在内部使用,因为这些是成熟的类,具有上面列出的所有优点。还有一点没有明确提到:它们(作为真实对象)可以存储状态,而普通函数不能。这可能会在以后产生很大的不同,并大大简化您的设计。当然,一旦您有了factory接口,您就可以轻松地将其产品的内部表示形式从普通函数更改为函子(然后再更改)。

如您所述,任何一种解决方案都适用于该问题。如果问题空间增加,工厂可能会更好。例如,如果将来还需要另一个依赖于语言的类或函数,也可以扩展工厂以返回该类或函数。函数指针表需要更多的更改来处理类似的事情。我会去工厂。问题域总是在增长。

谢谢。工厂更有意义。工厂返回函数指针而不是多态实例怎么样?谢谢他们的帮助。第二种方法只是模仿C++风格的C++运行时多态性(虚拟函数)。它在C++中对OOP的内置支持没有任何优势。