定义在其中执行不同代码路径的代码部分

时间:2018-06-29 15:49:33

标签: c++ c++11 visual-c++

是否可以在代码中定义执行不同代码路径的部分或范围,不使用全局或传递状态变量

出于调试目的,我希望能够用范围或#define包围一段错误代码,以临时打开此部分中的预定义调试行为,例如使用调试数据,更精确的数据类型,一种已通过验证的算法……这需要在多线程应用程序中工作,在该应用程序中,多个线程可能会同时执行同一共享代码,但只有其中一些从内部调用了此代码。定义的部分。

例如,下面的伪代码不起作用,但可能说明了我想做的事情。一个静态的昂贵函数,可以在多个地方同时调用:

Result Algorithms::foo()
{
#ifdef DEBUG_SECTION
    return Algorithms::algorithmPrecise(dataPrecise);
#else
    return Algorithms::algorithmOptimized(dataOptimized);
#endif
}

需要经常更新其实例的三类:

Result A::update()
{
    return Algorithms::foo();
}

Result B::update()
{
    Result result;

#define DEBUG_SECTION
        ...

        result = a.update() + 1337;

        ...
#undef DEBUG_SECTION

    return result;
}

Result C::update()
{
    return a.update();
}

如您所见,类A直接调用foo(),而在类B中,foo()通过调用a.update()和其他一些东西间接调用。让我们假设B::update()返回错误的结果,所以我希望只能在此位置使用foo()的调试实现。在C::update()中,仍应使用优化版本。

我的概念是在错误代码周围定义一个DEBUG_SECTION,该代码将在此位置使用调试实现。但是,这实际上不起作用,因为Algorithms::foo()在未定义DEBUG_SECTION的情况下被编译一次。在我的应用程序中,AlgorithmsABC位于单独的库中。

我希望在代码中定义的部分中,执行共享代码中的另一个代码部分。但是,在本节之外,我仍然希望执行原始代码,该代码在运行时将同时发生,因此我不能简单地使用状态变量。我可以在每个递归调用中传递的debugFlag内的每个调用中添加一个DEBUG_SECTION参数,然后将其提供给Algorithms::foo(),但这极易出错(您一定不能错过任何电话,但该部分可能很大,分布在不同的文件中,…)并且在较大的系统中非常混乱。有更好的方法吗?

我需要C ++ 11和MSVC的解决方案。

1 个答案:

答案 0 :(得分:1)

这可以通过使用模板来实现:

#ifndef Data_hpp
#define Data_hpp

#include
#include
#include

using namespace std;

class Data
{
public:
  Data();
  Data(char *Type, char *Material, int ID, char *Unit, double Min, double Max);
  ~Data();


  void getData(char *type, char *material, int *ID, char *unit, double *reading);

private:
  char type[32];
  char material[32];
  int ID;
  int reading;
  char unit[32];
  double min;
  double max;
  double generateData();
};
#endif 

另一方面,这意味着将函数定义移到标头中(或强制模板实例化,请参见these answers)。

缺点是每次您要在调试和发行版之间进行切换时,将对Algorithms :: foo()的调用从template<bool pDebug> Result Algorithms::foo() { if(pDebug) return Algorithms::algorithmPrecise(dataPrecise); else return Algorithms::algorithmOptimized(dataOptimized); } 更改为instance.foo<false>可能需要付出很多努力。如果您有多个受影响的调用,则可以使用编译时间const变量来减少键入的工作量,但无法确切知道您的代码,因此我无法估计这是否可行。

如果您的大多数代码使用该函数的优化版本,则还可以将模板参数设置为默认值为false(instance.foo<true>),以避免更改不会调用debug版本的现有代码。