首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C++中#define的合适使用场景是什么?

在C++中#define的合适使用场景是什么?
EN

Stack Overflow用户
提问于 2014-02-25 15:19:04
回答 5查看 1.2K关注 0票数 18

我知道基本规则,使用inlineenumconst代替#define,这不是我想要这个问题的原因。我想知道的是,在C++中使用#define宏时,什么是可接受的场景,以及如何使用。

请不要张贴问题或链接到“定义与常量”问题或“预处理器与编译器”的问题,我已经通过斯科特·迈耶斯的有效C++,我知道两者的优势。

然而,经过几个小时的网上冲浪,我感觉#define在C++中被视为某种失败者,但我相信在某种情况下,使用它是可以接受的,甚至是可取的。

为了开始工作,我想我能想到的一种方案是创建一个DEBUG宏,它基于它在代码中启用打印等功能,以实现调试目的。

EN

回答 5

Stack Overflow用户

发布于 2014-02-25 17:57:54

以下是使用#define是一个很好的解决方案的几个场景:

在保留函数签名的同时添加诊断信息:

代码语言:javascript
复制
#ifdef _DEBUG
#define Log(MSG)  Log((MSG), __FILE__, __LINE__);
#endif

条件编译和包含保护也是一个很好的例子(没有给出例子,因为您应该理解这一点:)。

样板代码是另一个例子,但这很容易被滥用。将宏用于样板代码的一个很好的例子是Boost.UnitTest中的BOOST_AUTO_TEST_CASE宏(一个更糟糕的例子是将Windows映射到它们的CHAR或WCHAR宏的WinAPI宏集)。

另一个很好的例子是提供编译器特定的关键字和设置:

代码语言:javascript
复制
#if (defined _WIN32) && (defined LIB_SHARED)
#   ifdef LIB_EXPORTS
#       define LIB_EXPORT __declspec(dllexport)
#   else
#       define LIB_EXPORT __declspec(dllimport)
#   endif /* LIB_EXPORTS */
#else
#   define LIB_EXPORT extern
#endif /* _WIN32 && LIB_SHARED */

用法:

代码语言:javascript
复制
// forward declaration of API function:
LIB_EXPORT void MyFunction(int);
票数 10
EN

Stack Overflow用户

发布于 2014-02-25 15:25:18

调试/发布或跨平台代码的简单设置。下面是我的程序示例:

代码语言:javascript
复制
void Painter::render()
{
    if (m_needsSorting)
    {
        _sort();
    }
    for (GameObject* o : m_objects)
    {
        o->render();
#ifdef _DEBUG
        o->renderDebug();
#endif
    }
}

对于win/ios,还有一个:

代码语言:javascript
复制
#ifdef _WIN32

#include "EGL/egl.h"
#include "GLES2/gl2.h"
#include <Windows.h>

#ifdef _ANALYZE
#include <vld.h>
#endif

#else // IOS
#import <Availability.h>
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
#import <Foundation/Foundation.h>
#endif

另一件事是库:

代码语言:javascript
复制
#ifdef VECTRY_INLINE
#define vinline inline
#else
#define vinline 
#endif

还有一些有用的东西,比如:

代码语言:javascript
复制
#define MakeShared(T) \
    class T; \
    typedef shared_ptr<T> T##Ptr
票数 8
EN

Stack Overflow用户

发布于 2014-02-25 16:52:39

有时,您希望无需重复永不结束的样板,或不必使用另一种语言来生成代码。From time to time,模板是不够的,您最终将使用Boost.Preprocessor来生成代码。

宏是“必需的”的一个例子是Boost.TTI (类型特征自省)。底层机制以某种方式滥用语言来创建几个强大的元函数,但需要大量的样板。例如,宏BOOST_TTI_HAS_MEMBER_FUNCTION生成一个matefunction,它检查一个类是否具有给定的成员函数。这样做需要创建一个新类,并且在没有宏的情况下不能很短(解决问题的非宏解决方案的示例here)。

有时,您还需要使用X-macros来生成代码。在编译时绑定东西是非常有用的。到目前为止,我不确定它们是否可以完全被取代,但不管怎样,你可以找到一些非常有趣的应用程序here的例子。

总而言之,宏可以是生成代码的强大工具,但需要谨慎使用。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22007222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档