3

当我在一个类中设计一个函数时,我想平衡我可以从中提取的信息。一些信息可能对调试有用,但作为函数的输出不是必需的。我举以下例子:

class A
{
   bool my_func(int arg1, int &output, std::vector<int> &intermediate_vec);
  {
     // do something
  }
}

在函数my_func中,std::vector<int> &intermediate_vec没有必要,因为我感兴趣的唯一信息存储在变量中output。但是,出于调试目的,我也有兴趣获取intermediate_vec,因为由于某种原因在函数内部检查此变量并不方便。因此,我正在考虑在A类中设计两个函数,一个用于调试,另一个用于实际应用。

    class A
    {
       // for debug
       bool my_func(int arg1, int &output, std::vector<int> &intermediate_vec);
      {
         // do something
      }
      // invoked by other programs 
      bool my_func(int arg1, int &output);
      {
         // do something
        std::vector<int> intermediate_vec
        return my_func(arg1, output, intermediate_vec);
      }
    }

我只是想知道是否有更好的方法来完成这项工作。谢谢。

4

2 回答 2

5

使用日志库并在调试日志级别记录这些中间值,而不是将它们收集为输出。

于 2013-06-20T13:25:19.527 回答
1

如果您打算intermediate_vec在一些调试后处理中使用它可能会很棘手。但是,如果您只打算使用它来打印结果,那就更容易了。

我不喜欢你的想法的主要事情是//do something在两个不同的地方拥有似乎完全一样的东西。这很容易出错并开始发展成为真正的 PIA,那时您将不得不使用十几个方法维护十几个类,其中一半有一些调试副本。逻辑上的每一次改变都必须以连贯的方式进行两次。

当我遇到类似的问题时,我正在考虑以下事情,以避免在执行条件日志记录和/或其他检测时使逻辑加倍。

#define DEBUG/NDEBUG 您只有一份带有一些预处理器条件的代码副本。

template < int DEBUG >. 效果基本相同,但语义不同。

模板方法可能会使编码有点复杂,但它允许在运行时使用这两个版本,这可能会派上用场。该#define方法根本不会改变 API,但如果您想要一些花哨的选择性或多级调试,您在设计代码时确实需要考虑。

当我必须拥有安全版本和快速版本的例程时,这两种功能方法在我的用例中是可以的。保险箱做了一些检查,然后调用了快速数字处理器。如果数字运算器用于循环或内部可以安全地假设您可以跳过检查,这将很有用。

如果调试版本较慢(例如,因为您需要初始化并填充一个长向量),那么您可能不想在发布代码中调用它。日志记录也是如此。如果您确实需要输出一个数字,但在调试版本中您最终会打印数兆字节的数据(例如计算向量的范数并打印向量本身),您将需要使用条件日志记录。

所以总的来说,这看起来更像这样:

class A
{
    bool my_func(int arg1, int &output, std::vector<int> &intermediate_vec);
  {
      if(DEBUG) {//fill in the vector}
      // do something
      if(DEBUG) {//print out some fancy stuff}

  }
  // invoked by other programs 
  bool my_func(int arg1, int &output);
  {
    std::vector<int> intermediate_vec;
    return my_func(arg1, output, intermediate_vec);
  }
}

当然,你可以在调试中使用短调用,但你不会得到向量。或者在无调试模式下完全调用,但是intermediate_vec没有意义。

任何避免复制粘贴应用程序逻辑的东西。我做到了,在改变逻辑时我非常痛苦。

于 2013-06-20T14:14:22.167 回答