• Effective C++(1-2) 编译器替换预处理器



    1 C++最主要的四部分:
    1. C
    2. Object-Oriented C++: 面向对象
    3. Template C++:泛型编程
    4. STL
    C++高效编程守则视状况而变化,取决于你使用C++的哪一部分。


    2 尽量以const, enum , inline替换 #define
    2.1 
    #define ASPECT_RATIO 1.653
    记号名称ASPECT_RATIO在被编译器识别之前,已经被预编译器替换为1.653了,所以名称ASPECT_RATIO有可能没进入记号表内。
    解决方法:
        const double AspectRatio = 1.653;
    性能影响:
        对浮点常量而言,使用常量可能币使用#define导致较小量的码,因为预处理“盲目地将宏名称ASPECT_RATIO”替换为1.653。

    2.2 关于const的一个知识点
    若要定义一个char*字符串,必须写const两次
    const char* const authorName = "Scott Meyers";
    若替换为String对象则更好:
    const std::string authorName("Scott Meyers");

    2.3 class专属常量
    static, 将常量的作用域限制于class内,且确保此常量至多只有一份实体。
    class GamePlayer {
    private:
        static const int NumTurns = 5;    //常量声明式
        int scores[NumTurns];                 //使用该常量
    };


    这里的NumTurns是个声明式,而不是定义式。一般情况下,这样做就足够了,声明并使用它,但是有两种情况需要你给出一个关于它的定义式:
    1 取这个class专属常量的地址
    2 编译器坚持要看到一个定义式
    这时候就需要一个额外的定义式:
    const int GamePlayer::NumTurns;   // 由于class常量已在声明时或得初值,因此定义时不可以再设初值。
    如果旧式的编译器不支持“in-class 初值设定”,那么可以把初值的设定放在定义式中:
    class CostEstimate {
    private:
        static const double FudgeFactor;
        ...
    };
        ConstEstimate::FudgeFactor = 1.35;  // 位于实现文件内


    2.4 enum hack
    如果你的编译器不够优秀,不允许"static整数型class常量"完成“in class初值设定”,那么,就有必要认识一下enum hack。先看一下补偿的做法:
    class GamePlayer {
    private:
        enum { EnumTurns = 5 };
        int scores[NumTurns];
    };

    现在来正式认识一下enum hack:
    1 enum hack的行为某些方面比较像#define而不是const,如:
    • 取一个enum的地址是不合法的,同样的,取一个#define的地址通常也不合法; 
    • 不允许一个指针或者引用指向某个enum常量; 
    • Enums和#defines绝不会导致非必要的内存分配。
    2 实用主义: 事实上,“enum hack”是template metaprogramming(模版元编程)的基础技术。



    2.5 形似函数的宏——>template inline函数
    // 以a和b的较大值调用f
    #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被累加一次

    神奇的事情就是,a的递增次数取决于“它被拿来和谁比较”。

    解决办法: template inline函数
    template<typename T>
    inline void callWithMax(const T& a, const T& b)
    {
        f ( a > b ? a : b);
    }


    小结:
    • 对于单纯常量,最好以const对象或者enum替换#define
    • 对于形似函数的宏, 最好改用inline函数替换#define
    参考:
    《Effective C++ 3rd》


  • 相关阅读:
    通过 curl 命令访问 K8S API
    k8s 调度 Affinity
    golang 定期发送 RA 报文
    Ticker 使用
    查看 host/container veth pair 关系
    Kubernetes 服务 service 的负载均衡分析
    698 TypeScript泛型的使用:泛型实现类型参数化,泛型接口,泛型类,泛型约束
    697 TypeScript接口的使用:接口的声明,可选属性,只读属性,索引类型,函数类型,接口继承,交叉类型,接口的实现,字面量赋值,枚举类型
    696 TypeScript类的使用:类的定义,继承,多态,成员修饰符,readonly,getters/setters,静态成员,抽象类abstract,抽象类演练,类的类型
    695 TypeScript函数类型:可选参数,默认参数,剩余参数,this类型,函数的重载,联合类型和重载
  • 原文地址:https://www.cnblogs.com/suzhou/p/3638969.html
Copyright © 2020-2023  润新知