C++工程中常用的宏定义(#define)

尽管说define有很多不足之处,很多时候我们需要使用const来替代define, 也可以使用typedef来替代define。

但是,在一些实际工程中,我们还是不可避免的使用到了define,这给我们带来了极大的方便。

1 定义头文件,防止重复包含 其实不是真正的防止重复包含头文件,而是忽略除了第一次之外的其他包含: http://blog.csdn.net/wangshubo1989/article/details/48310681

#ifndef WANGSHUBO_BASE_H_
#define WANGSHUBO_BASE_H_
...
#endif // WANGSHUBO_BASE_H_

2 定义变量

#define WANGSHUBO_SELF_MSG WM_USER + 29
static const std::string kDate = "2016-11-25";

3 分平台实现 对于一些快平台开发,完全可以使用define来包含不同的文件,或是实现不同的功能:

#if (MY_PLATFORM == MY_PLATFORM_WIN32)
#include <regex>
#include "sakura/win32/compact/dirent.h"
#endif
#if (MY_PLATFORM == MY_PLATFORM_IOS) || (MY_PLATFORM == MY_PLATFORM_MAC)
#include <ftw.h>
#endif
#if (MY_PLATFORM != MY_PLATFORM_WIN32)
#include <sys/types.h>
#include <errno.h>
#include <dirent.h>
#endif

4 定义级别 比如打日志,我们可能有很多种日志的级别:

void log_event(const char*format, ... ) {
#if MY_LOG_LEVEL == MY_LOG_LEVEL_ALL
    va_list args;
    va_start(args, format);
    char buf[MAX_LOG_LENGTH];
    vsnprintf(buf, MAX_LOG_LENGTH - 3, format, args);
    strcat(buf, "\n");
    WCHAR wszBuf[MAX_LOG_LENGTH] = { 0 };
    MultiByteToWideChar(CP_UTF8, 0, buf, -1, wszBuf, sizeof(wszBuf));
    OutputDebugStringW(wszBuf);
    WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, buf, sizeof(buf), nullptr, FALSE);
    printf("%s", buf);
    fflush(stdout);
    va_end(args);
#endif
}
void log_warning(const char*format, ... ) {
#if MY_LOG_LEVEL <= MY_LOG_LEVEL_WARNING
    printf("Warning : ");
    char buf[kMaxLogLen+1] = {0};
    va_list ap;
    va_start(ap, format);
    vsnprintf(buf, kMaxLogLen, format, ap);
    va_end(ap);
    printf("%s", buf);
    printf("\n");
#endif
}
void log_error(const char*format, ... ) {
#if MY_LOG_LEVEL <= MY_LOG_LEVEL_ERROR
    printf("Error : ");
    char buf[kMaxLogLen+1] = {0};
    va_list ap;
    va_start(ap, format);
    vsnprintf(buf, kMaxLogLen, format, ap);
    va_end(ap);
    printf("%s", buf);
    printf("\n");
#endif
}

5 定义导入导出函数

#define BASE_EXPORT __declspec(dllexport)
#else
#define BASE_EXPORT __declspec(dllimport)
#endif  // defined(BASE_IMPLEMENTATION)
#else
#define BASE_EXPORT __attribute__((visibility("default")))
#endif  // defined(WIN32)
#else
#define BASE_EXPORT
#endif  // defined(COMPONENT_BUILD)

6 单例模式

#define SINGLETON_DEFINE(TypeName)              \
static TypeName* GetInstance()                  \
{                                               \
    static TypeName type_instance;              \
    return &type_instance;                      \
}                                               \
                                                \
TypeName(const TypeName&) = delete;             \
TypeName& operator=(const TypeName&) = delete

7 禁止拷贝和赋值

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)

8 安全删除指针

#define MY_SAFE_DELETE(p) do { if(p) { delete (p); (p) = nullptr; } } while(0)
#define MY_SAFE_DELETE_ARRAY(p) do { if(p) { delete[] (p); (p) = nullptr; } } while(0)

9 定义命名空间

#ifdef __cplusplus
#define NS_MY_BEGIN                     namespace my_project {
#define NS_MY_END                       }
#define USING_NS_MY                     using namespace my_project
#else
#define NS_MY_BEGIN
#define NS_MY_END
#define USING_NS_MY
#endif

原文发布于微信公众号 - 程序员的酒和故事(cppdabaojian)

原文发表时间:2017-03-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网开发者交流社区

SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)

1003
来自专栏杨建荣的学习笔记

Oracle和MySQL竟然可以这么写这样的SQL?(r12笔记第99天)

今天看到Franck Pachot‏ 发了一个Twitter,意思是Oracle里的SQL还能这么写。猛一看确实让人有些意外。 ? 禁不住诱惑,自己也尝试了一番...

2815
来自专栏杨建荣的学习笔记

通过shell解析dump生成parfile(r2笔记76天)

当我们得到一个dump文件的时候,总是有些不太确定dump文件中是否含有一些我们原本不希望出现的表,如果在未知的情况下对dump文件进行操作时很危险的,比如我们...

2033
来自专栏Jerry的SAP技术分享

在ABAP里取得一个数据库表记录数的两种方法

这个函数使用起来很简单,只需要将想查询的数据库表名称维护进输入参数IT_TABLES:

1225
来自专栏杨建荣的学习笔记

使用hint来调优sql语句(72天)

最近生产发现有一个sql语句运行耗时达5000多秒。 抓出来sql_id一看,sql倒不是一个很长的语句。结构也很简单。如下。 select company_c...

2526
来自专栏木宛城主

利用Microsoft.VisualBasic中TextFieldParser解析器把CSV格式倒入数据库

写了个Demo,利用Microsoft.VisualBasic这个程序集中的TextFieldParser解析器解析CSV格式的文件,然后将解析的数据插入到相...

17010
来自专栏乐百川的学习频道

使用 pymysql 操作MySQL数据库

安装PyMySQL PyMySQL是一个Python编写的MySQL驱动程序,让我们可以用Python语言操作MySQL数据库。 首先,使用pip安装PyMyS...

2845
来自专栏专注 Java 基础分享

Java ---Listener监听器

在我们的web容器中,一直不断的触发着各种事件,例如:web应用启动和关闭,request请求到达和结束等。但是这些事件通常对于开发者来说是透明的,我们可以根据...

1849
来自专栏Jerry的SAP技术分享

使用ABAP代码创建S/4HANA里的Sales Order

其中红色区域的值是我代码里硬编码的,而蓝色是函数SD_SALESDOCUMENT_CREATE自己创建的。

756
来自专栏逍遥剑客的游戏开发

哇哈哈, 终于天上掉箱子了

934

扫码关注云+社区