Effective C++ tips day2

来源:互联网 发布:php session同步 编辑:程序博客网 时间:2024/06/08 19:50

        9.尽量以const, enum, inline替换 #define

        这个条款表述为”宁可以编译器替换预处理器“或许更好一些,因为或许 #define不被视为语言的一部分,这也正是它的问题所在。比如,当我们做出这样的事情:

#define ASPECT_RATIO 1.653
        记号名称ASPECT_RATIO也许并没有被编译器看见,在编译器处理源码之前,它就被预处理器移走了。于是记号名称ASPECT_RATIO有可能没有进入记号表(symbol table)内,于是当我们使用这一常量获得一个编译错误信息时,可能会带来困惑,因为这个错误信息也许会提到1.653而不是ASPECT_RATIO。如果ASPECT_RATIO被定义在一个非我们所写的头文件内,我们肯定对1.653以及它来自何处毫无概念,于是我们将为追踪它而浪费时间。

        解决方法是用一个常量替换上述的宏(#define),从而将名称记入符号表:

const double AspectRatio=1.653

        对于浮点常量(就像本例)而言,使用常量可能比使用#define导致较小量的码,因为预处理器”盲目将宏名称ASPECT_RATIO替换为1.653”可能会导致目标码(object code)出现多份1.653,若改用常量AspectRatio绝不会出现相同情况。

        另外,#define并不重视作用于(scope),一旦宏被定义,它就在其后的编译过程中有效(除非在某处#undef)。

        此外,我们可以利用template inline函数来获得宏所带来的效率以及一般函数的所有可预料行为和类型安全性(type safety):

template<typename T>inline void callWithMax(const T& a, const T& b){        f(a>b?a:b)}
        虽然我们有了consts、enums和inlines,但是我们对于预处理器的依赖并未完全消除,#include仍然是必需品,而且#ifdef/#ifndef也继续扮演着控制编译的重要角色。目前还不到预处理器全面引退的时候,但至少,我们应该明确给予它更长更频繁的假期。

        总的来说,我们记住两条:

        1)对于单纯的常量,最好以const对象或者enums替换#defines;

        2)对于形似函数的宏(macros),最好改用inline函数替换#defines。


        10.static关键字   

        static关键字用于对函数或者变量进行修饰。

        静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值。静态变量或静态函数只有本文件内的代码才可以访问它,它的名字在其他文件中不可见。

        static关键字主要有一下三种用法:

        1)函数内部声明static变量,可以作为对象间的一种通信机制。如果一个局部变量被声明为static,那么将只有唯一的一个静态分配的对象,它被用于在该函数的所有调用中表示这个变量。这个对象将只在执行线程第一次到达它的定义时初始化。

        2)局部静态对象。对于局部静态对象,构造函数是在控制线程第一次通过该对象的定义时调用,在程序结束时,局部静态对象的析构函数将按照它们被构造的相反顺序逐一调用。

        3)静态成员和静态成员函数。如果一个变量是类的一部分,而不是类的各个对象的一部分,它就被称为是一个static静态成员。一个static成员只有唯一的一份副本,而不像常规的非static成员那样在每个对象里各有一份副本。同理,一个需要访问类成员,而不需要针对特定对象去调用的函数,也被成为一个static成员函数,例如:

class Widget {public:...static int fun(int x = 0);...}int a = Widget::fun();
        对于类的静态成员函数而言,它只能访问类的静态成员(变量或函数),毕竟它并未与类的实例对象绑定。


        今天的介绍就到这里了,期待明天再见~


原创粉丝点击