宏可以返回对象吗?
#define macro1 {obj1}
既然宏是文本替换,我可以使用像macro1.function1()这样的宏吗?
谢谢。
宏永远不会返回任何内容。宏返回代码的文本表示,该代码将在编译之前粘贴到程序中使用它的位置。
了解C 预处理器。
所以:
#define macro1 {obj1}
int main() {
macro1
}
...将像您编写的那样进行编译
int main() {
{obj1}
}
这只是文本替换,可以选择使用参数。
如果您使用 GCC,您可以使用
cpp
工具查看预处理后程序的样子:
# cpp myprog.cpp myprog.cpp_out
通常将宏与对象混合是不好的做法,请使用模板代替。
宏在对象方面的一个已知用法是使用它们来访问单例(但这通常不是一个好主意):
#define LOGGER Logger::getLogger()
...
LOGGER->log("blah");
您还可以使用预处理器在编译时选择要使用的对象:
#ifdef DEBUG
# define LOGGER DebugLogger
#else
# define LOGGER Logger
#end
// assuming that DebugLogger and Logger are objects not types
LOGGER.log("blah");
...但是上述模板做得更好。
宏在预处理步骤(编译的七个阶段的一部分)期间触发文本替换。返回值发生在运行时。这个问题没有意义。
示例的宏将文本
macro1
替换为 {obj1}
。它仅用其他文本替换文本;它不知道对象或类的概念。
当你定义宏(并调用它)时,你总是可以看到编译器做了什么。宏的代码被简单地替换(就像复制粘贴一样)。
使用 gcc -E 编译。
例如这段代码
#define macro1 {obj1}
int main() {
int obj1;
macro1
}
使用 gcc -E example.c 进行编译时,我得到以下输出
# 1 "macro.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "macro.c"
int main() {
int obj1;
{obj1} //here your call gets expanded
}
函数宏不是 C++ 函数意义上的真正函数:它们只是预处理指令。
您的源文件首先由预处理器读取,宏被处理(扩展、替换等),然后将生成的源代码提供给编译器。
所以宏只不过是在源文件中“复制粘贴”文本。因此,您可以使用包含
return
语句的宏,但它只会在您的代码中被替换。
另请参阅类似函数的宏
我有一个功能:
bool CheckAndContinue(const bool p_test,
const std::string& p_errorMessage)
{
BOOST_CHECK_MESSAGE(p_test, p_errorMessage.c_str());
return p_test;
}
为此,由于 BOOST_CHECK_MESSAGE 位于函数中,因此结果将始终指向该函数中的行,而问题实际上位于调用
CheckAndContinue
的行上。
然后我必须做一个可以做同样事情的宏,这样指向的线就是调用
CheckAndContinue
的地方,这导致了下面针对我的具体情况的答案。
({ ... })
的使用)#define CHECK_AND_CONTINUE(p_test, p_errorMessage)\
({\
const bool result = (p_test);\
BOOST_CHECK_MESSAGE(result, p_errorMessage);\
result;\
})
注意我经过
const bool result = (p_test)
,因为如果我打电话给const bool success = CHECK_AND_CONTINUE(TimeConsumingFunctionOrFunctionThatModifyAValue(param))
,如果我有:
#define CHECK_AND_CONTINUE(p_test, p_errorMessage)\
({\
BOOST_CHECK_MESSAGE(p_test, p_errorMessage);\
p_test;\
})
由于宏的工作原理,
TimeConsumingFunctionOrFunctionThatModifyAValue(param)
将被调用两次(在p_test
使用时),然后耗时将消耗两次,如果修改一个值将修改两次(一个简单的值增量将增加例如两次)。