2017-06-19 63 views
0

我正在制作一个小型系统,我希望能够在整个系统中切换“详细”文本输出。使控制台输出成为“详细”的最快方法

我做了一个名为globals.h:

namespace REBr{ 
    extern bool console_verbose = false; 
} 

如果这是真的我希望我所有的类打印一条消息到控制台时,他们正在建设,自毁,复制或做几乎任何东西。

例如:

window(string title="",int width=1280,int height=720): 
Width(width),Height(height),title(title) 
{ 
    if(console_verbose){ 
     std::cout<<"Generating window #"<<this->instanceCounter; 
     std::cout<<"-"; 
    } 
    this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL); 
    if(console_verbose) 
     std::cout<<"-"; 
    if(this->window) 
    { 
     this->glcontext = SDL_GL_CreateContext(window); 
     if(console_verbose) 
      std::cout<<"."; 
     if(this->glcontext==NULL) 
     { 
      std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl; 
     } 
    } 
    else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl; 
    if(console_verbose) 
     std::cout<<">done!"<<endl; 
} 

现在你可以看到我有很多在构造IFS的。我真的不想这样做,因为这会减慢我的申请。我需要这样做,尽可能快地移除“加载栏”(这有助于我确定程序停止运行的功能)。

什么是最好的/最快的方法来完成这个?


万万在我的系统是命名空间REBr

+1

将''console_verbose'标记为'constexpr'。如果它们的表达式被评估为“false”,那么它显然会导致编译器优化所有的“if”。 – Alexey

+1

此外,如果你想避免输入'if(...)''每一次,只需定义一个宏#define VERB_STREAM if(console_verbose)std :: cout'并使用它像'VERB_STREAM <<“生成窗口#”<< this-> instanceCounter <<' - ';' – chtz

+0

你应该也看到这个问题:https://stackoverflow.com/q/6692238/1632887 – seleciii44

回答

1

一些变体实现的是:

  1. 使用一些记录库。这是最好的选择,因为它给你最大的灵活性和一些有用的经验;)你不必设计一些东西。例如,看看Google GLOG
  2. 定义一些宏,允许您通过仅更改宏来打开/关闭所有这些日志。但要正确地写出这样的marco并不那么容易。
  3. 将您的条件标记标记为constexpr。这样你可以切换标志,并且根据其值,编译器将在已编译的程序中优化if。但if仍然在代码中,所以它看起来有点笨重。

无论如何,所有这些选项都需要程序重新编译。不用重新编译就不可能达到最大速度。

+0

非常丰富,非常详细,包括多个答案。谢谢! – MoustacheSpy

0

我经常使用支持调试水平的Logger类下。一个调用可能如下所示:

logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2); 

Logger类支持多个调试级别,因此我可以微调调试输出。这可以在任何时候通过命令行或调试器进行设置。 Log语句使用非常像printf的可变长度参数列表。

+0

您究竟如何实现这个课程?你是否为你想要使用它的每个函数创建一个实例,或者你在创建一个全局实例。如果是的话,为什么不在一个名称空间内创建一些函数和变量? – MoustacheSpy

+0

@MoustacheSpy:我在我的主例程中实例化一个全局实例,以便启动是可预测的。由于我的应用程序几乎完全是面向对象的,所以我使用类/方法来覆盖函数,但这有点武断,超出了封装的明显优势。另外,如果多个线程正在访问日志,则需要线程安全保护。该类可以使用多态性使用线程安全和非线程安全的调用。 – Bruce

0

Google's logging module在业界广泛使用,并支持您可以从命令行设置的日志记录级别。例如(从他们的资料为准)

VLOG(1) << "I'm printed when you run the program with --v=1 or higher"; 
VLOG(2) << "I'm printed when you run the program with --v=2 or higher"; 

您可以在这里找到的代码https://github.com/google/glog并在doc/文件夹中的文档。