Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.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++ 清除预处理宏_C++_Macros_Refactoring_C Preprocessor_Command Line Arguments - Fatal编程技术网

C++ 清除预处理宏

C++ 清除预处理宏,c++,macros,refactoring,c-preprocessor,command-line-arguments,C++,Macros,Refactoring,C Preprocessor,Command Line Arguments,这是一个奇怪的问题,所以我必须提供一些背景知识。我有一个C++项目,我正在清理,我想清理一下。我要处理的主要问题是大量滥用项目核心组件中使用的预处理器宏。有一个文件包含大量的#define文件,这些文件在编译和使用程序之前被注释/取消注释,以便切换不同算法的使用。我更愿意使用命令行参数来实现这一点,而不是每次尝试不同的算法时都重新编译。问题在于,代码中交织着太多的#ifdef,因此似乎不可能简单地为每个算法重构代码 我被告知,这背后的原因是,这应该是一个实时系统,它将处理毫秒单位的时间,并且这个

这是一个奇怪的问题,所以我必须提供一些背景知识。我有一个C++项目,我正在清理,我想清理一下。我要处理的主要问题是大量滥用项目核心组件中使用的预处理器宏。有一个文件包含大量的
#define
文件,这些文件在编译和使用程序之前被注释/取消注释,以便切换不同算法的使用。我更愿意使用命令行参数来实现这一点,而不是每次尝试不同的算法时都重新编译。问题在于,代码中交织着太多的
#ifdef
,因此似乎不可能简单地为每个算法重构代码

我被告知,这背后的原因是,这应该是一个实时系统,它将处理毫秒单位的时间,并且这个组件中的代码被调用了很多次,因此进行
if
检查会对我们的性能产生不利影响。如果要尝试其他算法,必须设置适当的标志并重新编译,以优化性能

所以我要问大家的问题是:

有没有什么方法可以让我不用这些宏,而是使用命令行参数,而不会严重影响性能,也不会修改逻辑和代码?


我考虑的一个选项是,尝试为每个可能的算法组合编译此组件的版本,然后选择将由提供的命令行参数组合定义的版本。但据我的朋友说,组合的数量太多,这是不可行的。我自己还没有计算出这些数字,但考虑到他在这段代码中投入了多少精力,我会相信他的话

您分析过有问题的代码了吗?假设if语句减慢了程序的速度听起来像是过早的优化,这是一种代码味道。

啊,人们用CPP进行创作可能造成的暴行

首先,你需要决定你有多想这样做。在C++中。处理这种情况的正确方法是构建一个类集合,这些类表示存在差异的地方,然后将差异隐藏在接口后面

DifferentialEquationIntegrator <:
     Runge-Kutta Integrator
     Eulers Method Integrator

differentiesquationintegrator有一种模式可以处理这种问题:策略

您选择一次希望使用的策略(算法),然后将对象传递给其他人。这当然需要工厂建立正确的战略目标

对于交织码,公共码应该被分解


无论如何,如果您不确定并且担心可能会破坏某些东西,那么在尝试更改程序之前,先编写一系列单元测试。通过这种方式,如果重构过程中出现任何故障,那么很有希望它会被测试捕获。另外,尝试一点一点地重构(例如,一个文件一个文件,或者任何有意义的单元)。

如果我需要使用可选算法,在运行时选择它们,我会使用某种哈希表。我的算法是具有相同签名的函数,因此我可以创建指向函数的指针数组,并通过数组中的索引调用它们(索引可以解析为命令行参数)。虚拟性(如许多设计模式)不会对性能造成影响,而“如果”也不会对性能造成影响(如手动选择算法)

一些代码:

// type of my funcs:
typedef void (*SolverFunc)( const SolverParams &sp );

// implementation for the algorithms:
void EulerSolver( const SolverParams &sp ) { ... }

void RhungeSolver( const SolverParams &sp ) { ... }

// my array of solvers:
static SolverFunc s_solvers [] = { EulerSolver, RhungeSolver };

// parsing command line params:
int main( int argc, char** argv )
{
    int solverIndex = ParseIndex(argv);
    s_solvers[solverIndex] ( .. params .. );
    return 0;
}
嗯,代码是c风格的,而不是c++风格的,但是这个想法值得考虑。p、 我不确定这个例子在语法上是否正确,对不起=)

这应该是实时的 将要处理的系统 毫秒时间单位

这是一个真正的问题

[…]进行if检查 会对我们的 表演

这不是个好理由

如果您的代码已经过性能基准测试并因此进行了优化(应该是这样的),那么这将适用。我无法想象在任何情况下,用
#defines
替换ifs都会获得显著的性能提升(除非ifs是通过比较字符串内容、使用顺序搜索或类似的灾难性性能来完成的)

因此,我敢打赌,使用宏的决定是在设计时选择的,这可能会导致过早优化(“过早优化是所有宏定义的根源”:D)

有什么办法可以摆脱我吗 这些宏使用 命令行参数,但没有重载 一鸣惊人 修改逻辑和代码

以下是一些可能的步骤(还有其他解决方案,但这一个根本不使用
if
s):

  • 在代码上定义一个基准并运行它(存储结果)

  • 根据多个可能的
    #define
    s查找代码的一个区域

  • 使用公共接口将定义移到函数后面

  • 在运行时,将参数与常量进行比较,并将指向所选函数的指针传递给客户机代码

    应避免的事项:

    • 多次执行比较;比较之后,您应该有一个选定的函数指针;应该传递该函数指针,而不是您的参数
    • 使用字符串(或<代码> char *<代码>或任何不是数字的比较)进行比较。比较字符串或在固定时间内不做的任何比较对性能关键代码来说是灾难性的,而不是使用<代码>比较参数值>如果考虑使用<代码>开关< /C> >语句>
    • 将大型结构作为参数传递给策略函数。传递应为don