6

このアプリケーションでは、独自のログ システムを作成しました。このロギング システムには、デバッグ、エラー、警告、通信、パフォーマンスなど、いくつかの異なるログ タイプがあります。特定のログ タイプを無効にするための#ifdef#endifが多数あります。これらの#ifdef#endifは、コードを読みにくくします。

これらの#ifdef#endifを削除し、メッセージがファイルに書き込まれる前にチェックすることを考えています。つまり、ロギング システムに対して「役に立たない」呼び出しがたくさんあるということです。これらの呼び出しは、書き込みアクティビティにはなりません。

これらの#ifdefおよび#endifこれらの「役に立たない」呼び出しなしで、ログタイプをオン/オフにするより良い方法はありますか? AND

4

2 に答える 2

7

次はどうでしょうか。

// comment out if not needed
#define ENABLE_LOG

#ifdef ENABLE_LOG
#  define LOG(x) x
#else
#  define LOG(x) (void) 0 
#endif

後で呼び出すことができます:

LOG(mylogger.call());

#elseDietrich Epp が提案したように、その部分を更新しました。

于 2013-10-22T17:20:29.583 に答える
7

非常にうまく機能するソリューションに加えて、#defineテンプレートを使用した代替案を提示したいと思います

template<bool B>
void log(std::string message){}

template<>
void log<true>(std::string message){log_internal(message);}

#define DEBUG true
#define COMMUNICATION false

...

log<DEBUG>("this message will be logged");
log<COMMUNICATION>("this message won't");

この#defineソリューションは、ほとんどの場合に非常に優れていますが、このソリューションを使用する理由がいくつかあります。

  • スコープが必要な場合があります。つまり、logデバイスがグローバル名前空間を汚さないようにします。このソリューションは、配置できないnamespace場所に配置でき#defineます。

  • できることとできないことをより厳密に制御する必要がある場合があります。このLOG(x)定義には、 - に何でも入れることができるという問題がありx、ロギングがオフになっている場合、問題は発生しません。

クラリビーに - あなたのコードはコンパイルして動作するかもしれません

LOG(std::cout << "Here!" << endl);

この特定のログがオフになっているためです。しかし、今から 2 年後のある日、誰かがロギングをオンにしていたるendl undefinedところでエラーが発生します。さらに悪いことに、ロギングをオンにすると、かなり前になくなったライブラリへのリンクが突然必要になったり (ロギングがこのライブラリで定義された関数を特別に呼び出していたため)、以前からインターフェイスが変更されていた (または完全に削除されていた) 関数を使用していることに気付くかもしれません。実話 :( )

編集

これを回答に追加するように求められました:

ログに記録しない場合 (空の関数)、関数呼び出しのオーバーヘッドがあるように見えるかもしれません。コンパイラが最適化するため、これは当てはまりません。これを確実にしたい場合はinline、関数にディレクティブを追加してください。

また、文字列コンストラクターが呼び出されないようにするために、これを anstd::stringから aに変更することもできますが、これもコンパイラーによって自動的に最適化される必要があります。const char *

とにかく、私が言ったように、これは本質的に解決策よりも優れているわけではありません#define。実際、私はまだ#define自分のプロジェクトで を使用していますが、このテンプレート ソリューションが望ましい特定の例がいくつかあります。

于 2013-10-22T18:15:15.870 に答える