我正在维护一个遗留的 MFC 应用程序,我看到了一种与 Object-Oriented Programming under Windows 上的模式完全相同的模式。书,相关部分是:
Persview.h
#ifndef _DEBUG // debug version in persview.cpp
inline CPersDoc* CPersView::GetDocument()
{ return (CPersDoc*)m_pDocument; }
#endif
Persview.cpp
#ifdef _DEBUG
CPersDoc* CPersView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPersView)));
return (CPersView*)m_pDocument;
}
#endif //_DEBUG
如果我在互联网上搜索该模式,我会发现它被广泛应用,因此我认为它是向导生成的代码。
我的问题是:将发布版本内联到 .h 文件并在 .cpp 文件上进行调试是否有任何优势或其他充分理由?为什么不将两者并排放在同一个文件中?
最佳答案
请注意,您引用的这本书出版于 1994 年。当时的 C++ 非常不同,而 Microsoft 的 C++ 编译器则不然。据猜测,inline
当时具有不同的语义,并指示编译器内联函数调用,即使在调试配置中也是如此。
除此之外,还有技术原因:编译器只能内联函数(如果它看到完整的定义)。如果您希望将其内联到不同的编译单元中,则函数定义需要位于头文件中。另一方面,您不能将非内联函数放置在 header 中,因为如果 header 包含在多个编译单元中,则会违反“单一定义规则”。在这种情况下,您会遇到链接器错误。
如果您希望摆脱代码重复并仍然获得相同的好处,您可以:只需将调试版本移动到标题中,将其标记为内联
,并删除预处理器条件。 ASSERT 在非调试配置中不会编译为任何内容,并且编译器可以(可能会)内联函数调用。对于调试配置,编译器不会执行任何优化,并发出函数调用的代码。函数调用在调试配置中是理想的,因为它们会产生更有意义的堆栈跟踪。
关于c++ - 函数在 h 文件上内联发布版本,并在 cpp 上实现调试版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50582840/