Effective C++学习笔记之#define

前言

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

 

内容

1、对于单纯常量spa

一、const指针

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

(1)常量指针

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

  • 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。class

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;

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

 

二、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];
};

 

2、对于形似函数的宏

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

  有个经典的宏问题:

#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;
}

 

总结

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

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

相关文章
相关标签/搜索