effective c++ note1

《Effectvie C++》读书笔记一

0.导读

1、  在真实项目的代码中,如果使用标准程序库元素,需要加上前缀std::。

2、  本书中,函数名和临时变量名都采用首个单词为小写,单词间大小写混合的方式。

3、  default构造函数包含二类:(1)不带实参;(2)每个参数都有缺省值。

4、  在构造函数前加上“explicit”的作用是:禁止编译器执行非预期的隐式类型转换。鼓励将构造函数声明为“explicit”类型。

5、  copy构造函数,如  Widget(const  Widget& rhs);

copy assignment操作符,如 Widget&operator=(const Widget& rhs);

注意:如果出现 Widget w1= w0, 这个调用的是 copy构造函数,因为是在w1被定义时调用的,当然需要调用构造函数,但是如果Widget w1; w1=w0;这种情况下w1已经被定义好了,执行w1=w0时候只能调用copy assignment操作符了。

6、  函数形参出现类对象,一般要声明为const &类型比较好。

7、  声明一个指针变量,最好加上前缀p,声明一个引用,带上前缀r,成员函数加上前缀mf。

8、  TR1: Technical Report 1,描述加入C++标准库的诸多新机制;这些机能以class template和funciton template形式体现,针对的题目有hash table,reference-counting smart pointers,regular expression等,所有TR1组件被置于命名空间tr1内,后者嵌套与命名空间std内。

9、  Boost:是一个组织,也是一个网站,提供可移植性、同僚复审、源码开放的C++程序库,大多数TR1以boost的工作为基础,在编译器厂家于其C++程序库含入TR1之前,boost是开发人员首选的替代品。

 

1.让自己习惯C++

1、  C++: 多重泛型编程语言、一个同时支持过程形式、面向对象、函数形式、泛型形式、元编程形式的语言。相关语言组成的联邦而非单一语言。

2、  尽量以const, enum,inline替换#define,如

#define ASPECT_RATIO  1.653应该替换为: const double AspectRatio = 1.653;

字符串常量一般定义为: const std::string   authorName(”aaa”);

如果要限制常量的作用域,将其放在类内部定义的话,需要声明为static类型,仅保留一个实体。

(1)新的编译器可以直接在类内部声明并赋值static常量。如

 class Widget{

pubic:

 static const double  AspectRatio = 1.653;

 };

 但是还必须为AspectRatio在类外面定义一个空间

const double  AspectRatio;//no initailization here

(2)对于有些旧的编译器而言,在头文件声明的static常量不能赋值,这种情况下需要在实现文件里定义该变量并且赋值。

class Widget{

pubic:

 static const double   AspectRatio;

 };

const double Widget:AspectRatio = 1.653;

(3)如果编译器不允许“static 整数型 class 常量”完成“in class处置设定”,可以改用所谓的“the enum hack”补偿做法。

3、对于单纯常量,最好以const对象获enum替换#define,

对于形式函数的宏,最好改用inline函数替换#define。

3、  const std:vector<int>::iterator iter : iter不可以修改移动,所指的元素可以修改,类似 T* const p;

std::vector<int>::const_iterator  iter2: iter2可以修改移动,但是所指的元素不可以修改,类似const T* P。

4、  类的operator操作符函数返回的类型最好定义为const类型,防止返回值再次被赋值。

5、  对于一般守则而言,转型是一个糟糕的想法。

6、  类中的函数推荐非const类型函数调用const类型函数,避免代码重复。Const成员函数调用none-const成员函数是一种错误的行为。

7、  对于内置类型变量,需要手工赋值初始化;对于类对象,也需要将其初始化。

8、  C++规定:对象的成员变量的初始化动作发生在进入构造函数本体之前。推荐采用成员初始化列表代替构造函数中的赋值动作,这样做的效率更高,而不要在构造函数本体中使用赋值操作,初始化列表列出的成员变量,其排列次序应该和它们在class中的声明次序相同

(1)      对于const和reference类型的成员变量,必须使用初始化列表。

(2)      如果构造函数中需要读写文件或数据库,则将这些动作写成单独的函数放在private区域供构造函数调用即可。

(3)      Base classed先于derivedclass构造,class的成员变量以其声明的次序被初始化,即使它们在初始化列表中次序被打乱。

9、  C++对“定义于不同的编译单元的none-local static对象”的初始化相对次序并无明确定义,因此需要采用将non-local static对象替换为local static对象的方式,即单例模式。为了免除“跨编译单元初始化次序”的问题,请以local static对象替换non-local static 对象,这样就能保证对象的构造函数一定会被调用,而不是想在non-loca static情况下可能仅仅是调用了声明的对象,不是具体定义构造好的对象。

(1)      non-local static

//widget.hpp

class Widget{

public:

    int getSize() {return10;}

};

extern Widget w;

 

// Demo.hpp

Class Demo{

public:

Demo (param)

{

    int size =w.getSize()//WARNNIG: Widget w可能还尚未初始化,程序崩溃

}

}

 

(2)      local static 形式

 

//widget.hpp

class Widget{

public:

    int getSize() {return10;}

};

 

//单例模式,reference-returning函数,

Widget&   get Widget()

{

    static Widget w;

    return w;

}

 

// Demo.hpp

Class Demo{

public:

Demo (param)

{

    int size = get Widget.getSize()//Widget w 已经被初始化

}

}

备注:从另一角度,这些函数“内含static对象”在多线程系统中具有不确定性, 任何一种non-const static对象,不论是local还是non-local,在多线程环境下“等待某事情发生”都会有麻烦,解决办法是:在程序的单线程启动阶段手工调用所有reference-returning函数,可以消除与初始化有关的“竞速形势力”(race conditions)。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值