Effective c++(01,02)

条款一:

视C++为一个语言联邦

 

条款二:

尽量以const、enum、inline替换#define

1、你所使用的名称可能并未进入记号表,从而带来一些编码和理解上的困惑。

#define ASPECT_RATIO 1.635

记号名ASPECT_RATIO可能从未被编译器看到;也许在编译器开始处理源码之前他就被预处理器移走了,于是记号名称ASPECT_RATIO从未进入记号表内。如果发生错误,可能错误信息会提到1.635而不是ASPECT_RATIO。如果刚好ASPECT_RATIO是在一个非你本人所写的头文件中,需要浪费时间跟踪。

解决方法就是以一个常量替代宏

const double ASPECT_RATIO = 1.635;

常量替换宏有两种特殊的情况:定义常量指针和class专属常量。为了将常量的作用域限制于class内,必须让它成为class的一个成员;而为了确保此常量至多只有一份实体,必须让它成为一个static成员。

2、无法利用#define创建一个class专属常量,因为#define并不重视作用域。一旦宏被定义,它就在其后的编译过程中有效(除非在某处被#undef)。这意味着#define不仅不能用来定义class的专属常量,也不能提供任何封装性,即没有private属性。而const可以。

3、认识enum hack

​​​​enum hack的行为更像#define而不是const,如果你不希望别人得到你的常量成员的指针或引用,你可以用enum hack替代之。(为什么不直接用#define呢?首先,因为#define是字符串替换,所以不利于程序调试。其次,#define的可视范围难以控制,比如你怎么让#define定义的常量只在一个类内可见呢?除非你用丑陋的#undef);

使用enum hack不会导致 “不必要的内存分配”;

enum hack是模板元编程的一项基本技术,大量的代码在使用它。当你看到它时,你要认识它;

class Game {
private:
    // static const int GameTurn;
    enum {GameTurn = 10};
    int scores[GameTurn];
};

上述数组的声明就是利用enum hack实现。

remember

对于单纯常量,最好以const对象或enum替换#defines;

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

TIPS
1、静态常量数据成员可以在类内初始化(即类内声明的同时初始化),也可以在类外,即类的实现文件中初始化,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化。通常c++要求对所使用的东西提供一个定义式,但如果它是一个class专属常量有事static且为整数类型(例如int, char,bool),则需特殊处理。只要不取它们的地址,可以生命并使用它们而无需提供定义式。但如果需要使用他们的地址或者编译器坚持需要看到一个定义式,就需要在类外提供定义式,而此时不用再赋初值
2、静态非常量数据成员只能且必须在类外,即类的实现文件中初始化;
3、非静态的常量数据成员只能且必须在构造函数的初始化列表中初始化;
4、非静态的非常量数据成员不能在类内初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化

总结一下(为了避免出错且方便记忆):

                                                                  非静态的量,在构造函数的初始化列表中初始化;

                                                                  静态量,在类外,即类的实现文件中初始化。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值