-1

为了使程序的一部分易于单元测试,我想让它采用一个函数表,该表可以指向操作系统原语(即报告我们可以提供一组剪贴板目标的函数)或测试版本。理想情况下,虽然我不希望在实时版本中使用函数表的开销,只是它借给代码的额外结构。所以我想用某种方式告诉编译器函数表永远不会改变,这样它就可以优化查找。像这样的东西(用于说明的简单实现):

#ifndef TEST
const
#endif
static struct {
    void (*reportTargets)(size_t targetc, const char **targetv);
    [...]
} interfaceToOutside
#ifndef TEST
= {
    reportTargetsLive,
    [...]
}
#endif
;

这可能会奏效吗?如果没有关于如何实现这一目标(或做得更好)的好建议?

4

2 回答 2

0

您可以使用静态内联函数创建 2 个结构,而不是函数指针。一个是测试用的,一个是真实的。现在,根据您实例化模板的方式,您要么处于测试模式,要么处于实时模式。

struct Live
{
    static void Report(const std::string& report) { ReportLive(report); }
};

struct Test
{
    static void Report(const std::string& report) { ReportTest(report); }
};

template<typename T>
class Reporter
{
public:
    void doReport()
    {
        //some stuff todo
        T::Report(report);
        //other stuff todo
    }
};

这只是一个想法。内联代码时,编译器将(完全)优化结构。此外,您可以通过实现不同的结构来选择不同的测试行为。

于 2013-06-03T10:28:43.563 回答
0

所以我想用某种方式告诉编译器函数表永远不会改变(...)

好吧,声明所有const(顺便说一句,你应该在和const之间交错第一个):staticstruct

#ifndef TEST
# define CONST const
#else
# define CONST 
#endif

static CONST struct {
    void (*CONST reportTargets)(size_t targetc, const char **targetv);
    [...]
} interfaceToOutside
#ifndef TEST
= {
    reportTargetsLive,
    [...]
}
#endif
;

#undef CONST

(我知道,宏名称不好)。

现在,

这可能会奏效(...)吗?

我认为是这样,但您仍应检查生成的汇编代码(/的-S选项)。gccg++

于 2013-06-03T09:27:46.897 回答