Effective C++学习笔记之#define

前言

  条款02:尽量以const、enum、inline替换#define;尽可能用编译器代替不必要的预处理器。

内容

一、对于单纯常量

1、const

  有两种特殊的const,常量指针和class专属常量;

(1)常量指针

  又分为常量指针、指针常量、指向常量的指针常量;

  • const double *p;或者 double const *p;const读作常量,*读作指针,为常量指针;

  本质是个指针,是指向一个常量的指针,也即指向的内容(*p)不可变。

  • double * const p;*读作指针,const读作常量,为指针常量;

  本质是个常量,是形容这个常量的类型是指针,也即指针指向不能改变。

  • const double * const p;不管是指针的指向还是指针的指向内容都是常量,即是指向常量的指针常量。

  实际栗子解释:

const double *p = &b 常量指针;不允许 *p = 6.66,因为常量指针的指向内容是常量不可变;但是允许 p = &c。

double * const p = &b 指针常量;不允许 p = &c,因为指针常量的指向是常量不可变;但是允许 *p = 6.66。

(2)Class的专属常量

  class专属常量是指常量的作用域只在class里,需要在const的基础上再添加static关键字。

    .h头文件里声明 static const double score;

    .cpp实现文件里设初始值 const double Student::score = 66.6;

(很多编译器不支持在声明的时候设置初始值,只能将声明和设初值分开)

2、enum

  如果遇到上述“不支持在声明的时候设置初始值”,就展现了enum的必要性。

eg:

class A
{
private:
  static const int LEN = 5;
  int score[LEN];
};

  如果编译器(错误地)不允许static整数型class常量完成 in-class 初值设定,就应该用enum来代替:

class A
{
private:
  enum {LEN = 5};
  int score[LEN];
};

二、对于形似函数的宏

  将简单的函数写成宏,能免去函数调用的一些开销,但是使用不当会得到预料之外的结果。

  有个经典的宏问题:

#define FINDMAX(a,b) ( (a) > (b) ? (a) : (b) )
FINDMAX(a++,b); //a被累加两次
FINDMAX(a++,b+10); //a被累加一次

  用 inline 来代替此类宏的使用,既能免去函数调用的开销,也能避免一些不可预知的错误。

  inline 将函数“内联” 起来了,在调用的时候是编译器使用相应的函数代码替换函数调用。编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了类似#define的隐患和局限性。

template <typename T>
inline T FindMax(const T& a, const T& b)
{
  return a>b?a:b;
}

总结

1、对于单纯常量,尽量用const、enum替换#define;

2、对于形似函数的宏,最好用inline函数代替#define;

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏take time, save time

初级程序员面试不靠谱指南(三)

二、指针的好基友的& 1.&的意义。说&是指针的好基友其实不恰当,因为&这个符号在C/C++不止有一种含义,但是因为其经常会和指针一起出现在被问的问题列表上,所...

3339
来自专栏决胜机器学习

有趣的算法(五) ——Dijkstra双栈四则运算

有趣的算法(五)——Dijkstra双栈四则运算 (原创内容,转载请注明来源,谢谢) 一、概念 近期看到算法书上,提到dijkstra双栈的方法,实现输入一...

6097
来自专栏诸葛青云的专栏

python入门:进来吧,给自己10分钟,这篇文章带你直接学会python

假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程。那么本教程将花费十分钟的时间带你走入Python的大门。本文的内容介于教程(Totur...

370
来自专栏转载gongluck的CSDN博客

python笔记:#008#变量的命名

变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名、函数名 名字 需要有 见名知义 的...

3694
来自专栏Golang语言社区

Go 语言的基本数据类型

0)变量声明 var 变量名字 类型 = 表达式 例: var num int = 10 复制代码 其中“类型”或“= 表达式”两个部分可以省略其中的一个。 1...

41311
来自专栏程序员与猫

常见的正则表达式解读释义

又名:写给正在学习前端的女友看的常见正则表达式解读。原文发布于 https://www.zybuluo.com/wddpct/note/728081 。 ...

2059
来自专栏老九学堂

【必读】C语言基础知识大全

C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使小伙伴对c语言有个初步认识。 例1:计算两个整数之和的c程...

5358
来自专栏一个爱吃西瓜的程序员

一文读懂正则表达式的基本用法

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过...

981
来自专栏PPV课数据科学社区

走近 Python (类比 JS)

Python 是一门运用很广泛的语言,自动化脚本、爬虫,甚至在深度学习领域也都有 Python 的身影。作为一名前端开发者,也了解 ES6 中的很多特性借鉴自 ...

40810
来自专栏IT可乐

Java数据结构和算法(六)——前缀、中缀、后缀表达式

  前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆...

2509

扫码关注云+社区

领取腾讯云代金券