• 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;

  • 相关阅读:
    Zookeeper and The Infinite Zoo(CF1491D)(位运算)
    树上差分
    最近公共祖先
    极角排序
    最长路spfa
    树的基础
    树的遍历~
    最小圆覆盖板子
    动态凸包(询问点是否在凸包内部)
    凸包内最大三角形
  • 原文地址:https://www.cnblogs.com/Christal-R/p/9519525.html
Copyright © 2020-2023  润新知