effective c++-让自己习惯c++

02:尽量用const,enum,inline替换define

(一)【忠告】

a) 对于常量,用constenum代替define

b) 对于形似函数,用inline代替define

(二)尽量替换掉define的原因:

a) define A 1.63出错时,报1.63出错;const int A=1.63出错时,报A出错。显然报变量名出错更加容易调试

b) define的可见范围不可控制,const修饰的常量可以被类封装

(三)常量替换define的两种特殊情况:

a) 当常量定义成指针时,要有两个const,即const int* const A=10;前一个const保证了指针A指向地址的内容不会发生变化,后一个const保证了指针A是个常量指针(*const A:常量指针),它指向的地址不会发生变化。

b) Class的专属常量

i. Class AAA{

Private:

Static const int num=10;

Data[num];};

支持静态变量内初始化的编译器可以这么干。

ii. Class AAA{

Private:

Static const int num;

Data[num];};

AAA::num=10;

不支持内初始化的编译器只能这么干,但这时候,Data数组就不知道大小,编译会出错

iii. Class{

Private:

enum{num=10};

Data[num];};

枚举中的常量可以被类成员直接引用。这样就避免了不支持静态变量初始化的编译器,无法实现上述做法的问题。并且enum不会被取到常量地址,如果不想被取到常量地址,也可以这么做。

(四)补习枚举类型enum

a) 定义enum Luo{a=’a’,b,c,d,e,f,g};

b) Luo是像int那样的类型名。enum Luo中的abc都是常量,且在程序中可以直接使用a来表示’a’enum的大小为4字节,由编译器决定,不以常量个数而变化。

c) 使用示例

int main(){

enum A{a='a',b,c,d,e,f,g,h,i,j,k};

cout<<sizeof(A)<< a <<endl;//4;97(‘a’的ascii值)表示可以直接用

A test;test = (A)9;

cout << test << endl;}

条款03:尽可能使用const

(一)【忠告】

a) Const可以被用来修饰任何作用域内的对象、变量(成员变量)、函数返回值(成员函数返回值)、函数参数(成员函数参数)、函数本身(成员函数本身)

b) 有些东西(比如返回值)声明为const,更容易排错

c) 可以使用mutable来释放编译器的bitwise-constness

d) constnon-const的实现没有什么区别时,可以用non-const来调用const的方法,使代码复用

(二)Const与指针

a) const int *Aconst * int Aint * const A

i. Const*的右边:表示指针A本身不是常量,指针A指向的地址可变,但地址中的内容物不可变

ii. Const*的左边:表示指针A本身是常量,指针A指向的地址不可变,但地址中的内容物可变

b) 指针作为全局变量,放在头文件中时

i. Const int * const A=5;表示指针指向地址不可变,且地址中的内容物亦不可变

(三)Const与迭代器

a) Const vector<int>::iterator it:表示迭代器本身是常量,不允许++it

b) Vector<int>::const_iterator it:表示迭代器所指向的地址内容不允许改变

(四)Const与类

a) Const修饰对象

i. Const对象被限制为只能调用const修饰的成员函数,因为non-const可能会改变对象的值

b) Const修饰成员变量

i. const修饰普通变量一样

c) Const修饰成员函数的参数

i. const修饰普通变量一样

d) Const修饰成员函数返回值

i. 可以帮助编译器排错If(a*b=c){··· }//经常少打一个=,当非const时,且ab均为某函数的返回值(对象),这个赋值动作就会被执行。但如果是const的话,那么因为常量不可被赋值,所以会报错,更容易排错了

ii.  如果函数返回值采用“值传递方式”【非引用,非指针】,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。所以,对于值传递来说,加const没有太多意义。

e) Const修饰成员函数本身

i. 成员函数可以凭借有无const修饰来重载Const一个版本、non-const又是另一个版本

ii. Const修饰成员函数,该成员函数不能更改任何non-static的成员变量,但可以使用mutable(修饰成员变量)来打破这个限制

iii. constnon-const成员函数相同时,non-const版调用const版可以代码复用

条款04:确定对象被使用前已被初始化

(一)【忠告

a) 内置类型需要手工初始化。

b) 其他类型初始化,由构造函数承担。

i. 构造函数初始化最好用初始化列表。比起在构造函数中在赋实参值初始化,初始化列表1.成员变量不用先被赋上随机值;2.实参赋值给成员变量又是一次copy3.形参到实参又是一次拷贝

ii. 初始化列表初始化顺序至于成员变量的声明顺序有关。

iii. Constreference定义时需要初始化的成员变量,需要在初始化列表中初始化。Static需要在类体外初始化(如果编译器支持内初始化,那么可以在定义时就初始化)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值