effective C++(第三版)读书笔记一——条款二:尽量以const,enum,inline替换#define

中“宁可以编译器替换预处理”算是另一种提法,不过这个应该是概括性的说法吧
主要事项注意如下:
1用const double AspectRatio=1.653;代替#define ASPECT_RATIO  1.653
  原因是预编译时define会被简单的替换,这样在编译时丢掉了ASPECT_RATIO,如果不正
  当使用了ASPECT_RATIO编译时提示出错的可能只是1.653,这时候查找起来麻烦多了
另一个原因是定义成变量后编译时只有一份拷贝,节约了代码
当然这个条款也有特例
1)当出现指针的时候要这样
const char* const autherName = "Scott Mayers";
即指针和其内容都不可变,当然如果是字符串string会比上面的char更合适
const std::string autherName("Scott Mayers");
2)注意class的专属常量,通过使得常量成为class的一个member将常量作用域限制在class内,而#defnie做不到。
通过使用static使常量只有一份拷贝
class GamePlayer(){
private:
static const int NumTurns = 5;
int scores[NumerTurns];
……
};
但上面给出的是声明而非定义,通常C++要求对任何东西的使用都要有定义式,但
像这种情况则可以例外,只要不取他们的地址就可以。
如果取地址,或者因为编译器的原因要求定义式,这定义如下:
const int GamePlayer::NumTurns;//将此式放进一个实现文件而非头文件
class常量已经声明了初值,这里就不在设了。
旧的编译器可能不支持以上语法,那么你可以把初值放在定义式中。
这又有例外了,编译器期间需要一个calss常量时(如数组scores[]的声明式),编译器又不允许“static整数型class常量”完成“in class”初值设定,可以改用“the enum hack”来实现。
class GamePlayer {
private:
  enum { NumTurns = 5 };
  int scores[NumTurns];
……
}
emum hack的方法其实和#define又有些像了,例如不能取得地址,如果不想让人获得地址或者reference这样正好。 另外Enmus和,#define绝不会导致不必要的内存分配(为什么这么说?难道编译器不会为Enmus分配内存?#define不知在每次调用都会占一次内存吗?const只有一份拷贝,不管调用多少次,难道const比define还多费了内存??)
3)回到预处理器来,另一个常见的#define误用情况是以它实现宏(macros)。
宏看起来像函数,但不会招致函数调用(function call)带来的额外开销。
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
无论何时当你写出这种宏,必须记住为宏中的所有实参加上小括号,即使是加了括号,也还是会有问题。如
int a = 5, b = 0; 
CALL_WITH_MAX(++a, b);      //a被累加二次 
CALL_WITH_MAX(++a, b+10);   //a被累加一次在这里,调用f之前,a的递增次数竟然取决于"它被拿来和谁比较"!
用inline函数来解决这个问题
template inline函数(见条款30):

    template<typename T>                    //由于我们不知道具体会操作什么类型,所以用模板 
    inline void callWithMax(const T& a, const T& b) //T是什么,所以采用 
    {                                //pass by reference-to-const. 
      f(a > b ? a : b);                   //见条款20. 
    }

      对于单纯常量,最好以const对象或enums替换#defines。
      对于形似函数的宏(macros),最好改用inline函数替换#defines
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值