zoukankan      html  css  js  c++  java
  • 「C++」条款02 & 03:#define & const

    •  关于 #define
    #define ASPECT_RATIO 1.63
    const int AspectRatio 1.63;

    如果我们的代码中用到了 ASPECT_RATIO 宏,编译器只会简单粗暴的把其替换为 1.63,如果后期我们调试的过程中莫名其妙的遇到了 1.63 可能追踪半天都不会清楚问题发生在什么地方。另外每次的替换,相当于扩大了代码体积,违背了重用的原则。再来看看 const 下定义的 AspectRatio,完全避免了上面几种情况的发生。

    #define 往往也会在我们意料之外出错,如下面的情况:

    #define MAX_NUM ((a) > (b) ? (a) : (b))
    
    int a = 5, b = 0;
    MAX_NUM(++a, b);    
    MAX_NUM(++a, b + 10);

    第一个 MAX_NUM 宏 ++a 执行了 2 次,而第二个只执行了 1 次,这显然不是我们想要达到的效果,下次还是老老实实写成函数吧。

    • static const

    以前用类封装函数的时候,想着定义一个 const 常量,而且控制在类的作用域里面。下面的代码展示了几种可行的情况:

    class GamePlayer {
    private:
        static const int NumTurns = 5;
        int scores[NumTurns];
        ...
    };
    
    class GamePlayer {
        enum { NumTurns = 5 };
        int scores[NumTurns];
        ...
    };
    • const 的几种情况

    关于 const 的几种定义就不在叙述了,下面主要针对 const 的几种关键用法:

    class BigNum { };
    const BigNum operator * (const BigNum& lhs, const BigNum& rhs);

    这里不禁会有疑惑,为什么我们没有 return by reference 却加了一个 const 的在函数前面呢?想想如下情况:

    BigNum a, b, c;
    if (a * b = c) {
        ...
    }

    如果有人粗心的把 == 写成 = 就会引发程序的逻辑错误,如果设置返回为 const 的话,编译器就会帮助我们检测出来这些低级的逻辑问题。

    再考虑关于“const 成员函数”的用法,也是 C++ const 几种经典案例之一:

    class CTextBlock {
    public:
        const char& operator[] (size_t position) const {
            ...
            ...
            return text[position];
        }
        char& operator[] (size_t position) {
            ...
            ...
            return text[position];
        }
    private:
        char* text;
    };
    
    // 此时调用 const 成员函数
    void print(const CTextBlock& ctb) {
        cout << ctb[0];
    }
    // 此时调用 non-const 成员函数
    void print(CTextBlock& tb) {
        cout << tb[0];
    }

    也许你会发现两个成员函数执行的操作会是相同的,这样无疑重复了很多代码量,书中给出了下面的一种做法,让 non-const 调用 const 成员函数:

        const char& operator[] (size_t position) const {
            ...
            ...
            return text[position];
        }
        char& operator[] (size_t position) {
            ...
            ...
            ...
            return const_cast<char&>                    // 去掉 const 属性
                    (static_cast<const CTextBlock&>     // 为 *this 加上 const
                        (*this)[position]);             // 调用 const op[]
        }

    最后还有一个要点就是,对于编译器来说,const 成员函数里面是不允许修改类成员变量的,这有时候会给我们带来麻烦,但是可以通过关键字 mutable 来解决,例如:mutable size_t length;

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    【Rust】无关联类型
    【Rust】trait克隆
    【Rust】trait动态返回
    【Rust】trait迭代器
    【Rust】特质trait
    【Rust】运算符重载
    【Rust】trait超集
    【Rust】trait删除
    【Rust】trait实现
    wpf之数据模板 安静点
  • 原文地址:https://www.cnblogs.com/kedebug/p/3125841.html
Copyright © 2011-2022 走看看