使用预处理器宏取消定义函数
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++中的宏禁用。我已经阅读了这个线程:使用宏禁用函数,但
#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
}
};
相关文章:
- C++宏定义和取消定义
- 在宏中定义然后取消定义预处理器变量
- 如何在不取消定义类型的情况下为 C++ 中的类型编写 getter?
- 在Ubuntu 12.04.1 LTS libssl-libcrypto上取消定义引用
- 取消定义引用..:从模板类继承
- 我可以显式取消定义特定函数的宏吗?
- C++/Qt定义/取消定义Qt_NO_SESSIONMANAGER宏
- 需要一个头文件,取消定义在windows.h中的所有定义
- 在取消定义宏函数之前,在宏函数中使用/复制宏变量的值:可能吗?
- 如何在运行时取消定义和定义预处理器值
- 在 C++ 中取消定义对函数的引用
- 取消定义静态函数的引用错误
- 使用预处理器宏取消定义函数
- 如何取消定义_MSC_VER
- 可以隐藏(或取消定义)typedef吗
- 取消定义一个已定义的头文件
- C++编译错误:取消定义对'printMaze(int const(*)[16],int,int)'的引用,Id 返回 1 退出状态
- 定义一个宏,然后取消定义之前未定义的宏
- 单元测试 - 是否可以在C++(Visual Studio)中取消定义类
- 如何取消定义 Visual Studio 2012 的系统定义