簡體   English   中英

使用預處理器宏來定義未定義的函數

[英]Undefining functions using preprocessor macros

我有一個用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是一個類的事實有關,但我不知道該怎么做。 一些幫助?

實際上,如果這些是成員函數,那么“無聲”版本將擴展為無意義:

log.(void)sizeof(stuff);

您可以定義一個不執行任何操作的成員函數,以及吞下其參數的宏:

void nothing() {}

#define processMessages(...) nothing()

然后使用“靜默”版本將提供應該編譯為空的有效代碼:

log.nothing();

這樣做的缺點是(a)你依靠編譯器內聯空函數,而不是生成函數調用; (b)在靜默模式下編譯時不會檢查參數的語法。

如果您的編譯器支持可變參數宏,您可以簡單地定義具有空替換的宏:

#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

但是,這僅在函數不是類或命名空間的成員,而是真正的全局函數時才有效。

我想建議你以不同的方式工作。 只需聲明接口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
 }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM