1

このタイプの関数を使用して C++ で記述されたログ システムを作成しました。

    void processMessages();
    void DEBUG_MSG(const std::string& appender,const char* msg, ...);
    void INFO_MSG(const std::string& appender,const char* msg, ...);
    void WARNING_MSG(const std::string& appender, const char* msg, ...);
    void ERROR_MSG(const std::string& appender, const char* msg, ...);
    void FATAL_MSG(const std::string& appender, const char* msg, ...);

C++ でマクロを使用して無効にしたい。私はこのスレッドを読みました: MACROS を使用して機能を無効にしますが、

#ifdef GLOG_SILENCE
        #define processMessages     (void)sizeof
        #define DEBUG_MSG           (void)sizeof
        #define INFO_MSG            (void)sizeof
        #define WARNING_MSG         (void)sizeof
        #define ERROR_MSG           (void)sizeof
        #define FATAL_MSG           (void)sizeof
#else //GLOG_SILENCE
        void processMessages();
        void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        void INFO_MSG(const std::string& appender,const char* msg, ...);
        void WARNING_MSG(const std::string& appender, const char* msg, ...);
        void ERROR_MSG(const std::string& appender, const char* msg, ...);
        void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE

正しく動作しません。次のようなエラーが発生し続けます。

../src/test_core.cpp:2 からインクルードされたファイル:

../src/test_Log.h: In member function ‘virtual void LogTestFixtureTest_defining_SILENCE_macro_avoids_write_and_processing_activity_from_log_Test::TestBody()’:
../src/test_Log.h:63: error: expected unqualified-id before ‘(’ token
../src/test_Log.h:63: error: expected primary-expression before ‘void’
../src/test_Log.h:63: error: expected ‘;’ before ‘sizeof’
../src/test_Log.h:64: error: expected unqualified-id before ‘(’ token
../src/test_Log.h:64: error: expected primary-expression before ‘void’
../src/test_Log.h:64: error: expected ‘;’ before ‘sizeof’

問題は Log がクラスであるという事実に関連していると思われますが、その方法がわかりません。手助け?

4

3 に答える 3

4

実際、これらがメンバー関数である場合、「サイレント」バージョンはナンセンスに拡張されます。

log.(void)sizeof(stuff);

何もしないメンバー関数と、引数を飲み込むマクロを定義できます。

void nothing() {}

#define processMessages(...) nothing()

次に、「サイレント」バージョンを使用すると、何もコンパイルされない有効なコードが得られます。

log.nothing();

これの欠点は、(a)空の関数をインライン化するためにコンパイラーに依存しており、関数呼び出しを生成しないことです。(b)サイレントモードでコンパイルする場合、引数の構文はチェックされません。

于 2012-04-19T10:33:09.570 に答える
0

別の方法で作業することをお勧めします。インターフェースILoggerを宣言してから、次のようなさまざまなロガーに実装します。

class ILogger{
 public:
        virtual void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        virtual  void INFO_MSG(const std::string& appender,const char* msg, ...);
        virtual  void WARNING_MSG(const std::string& appender, const char* msg, ...);
        virtual  void ERROR_MSG(const std::string& appender, const char* msg, ...);
        virtual  void FATAL_MSG(const std::string& appender, const char* msg, ...);
        virtual ~ILogger(){}
};

ファイルロガーの場合

class FileLogger : public ILogger{
 public:
        void DEBUG_MSG(const std::string& appender,const char* msg, ...){....}
        void INFO_MSG(const std::string& appender,const char* msg, ...){....}
        void WARNING_MSG(const std::string& appender, const char* msg, ...){....}
        void ERROR_MSG(const std::string& appender, const char* msg, ...){....}
        void FATAL_MSG(const std::string& appender, const char* msg, ...){....}
        virtual ~EmptyLogger(){}
};

and the empty logger like:

空のロガーのために

class EmptyLogger : public ILogger{
 public:
        void DEBUG_MSG(const std::string& appender,const char* msg, ...){do nothing here}
        void INFO_MSG(const std::string& appender,const char* msg, ...){do nothing here}
        void WARNING_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        void ERROR_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        void FATAL_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        virtual ~FileLogger(){}
};

その後、ロガーを作成する場所で、別のタイプのロガーを生成するために工場でマクロを作成することができます。

class LoggerFactory{
public:
 static ILogger* getLogger(/*loggertype as argument*/){
   #ifdef GLOG_SILENCE
    /* create a normal logger*/
   #else
     return new EmptyLogger();
   #endif
 }
};
于 2012-04-19T10:50:01.473 に答える
0

コンパイラが可変長マクロをサポートしている場合は、空の置換を使用してマクロを定義できます。

#ifdef GLOG_SILENCE
        #define processMessages(_1, _2, ...)
        #define DEBUG_MSG(_1, _2, ...)
        #define INFO_MSG(_1, _2, ...)
        #define WARNING_MSG(_1, _2, ...)
        #define ERROR_MSG(_1, _2, ...)
        #define FATAL_MSG(_1, _2, ...)
#else //GLOG_SILENCE
        void processMessages();
        void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        void INFO_MSG(const std::string& appender,const char* msg, ...);
        void WARNING_MSG(const std::string& appender, const char* msg, ...);
        void ERROR_MSG(const std::string& appender, const char* msg, ...);
        void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE

ただし、これは、関数がクラスまたは名前空間のメンバーではなく、真のグローバル関数である場合にのみ機能します。

于 2012-04-19T10:36:45.880 に答える