《Effective C++》第三版笔记

阅读此笔记前,请先阅读 《Effective C++》第二版笔记    《More Effective C++》笔记

这里只记录与上面笔记不同的条款,主要是 "面对对象+模板+内存管理" 三个方面

1、视 C++ 为一个语言联邦

可以分为 C、C with Object、Template C++、STL 四个次语言,不同次语言的高效编程守则可能不一样,比如 C 部分 pass-by-value 通常比 pass-by-reference 高效,而对于 Object-Oriented C++ 而言,由于用户自定义的构造函数和析构函数的存在, pass-by-reference-to-const 往往更好,而到了 STL 中,迭代器和函数对象都是在 C 指针上塑造出来的,所以对 STL 的迭代器和函数对象而言,旧式的 pass-by-value 守则再次适用。

3、尽可能使用 const

使用 const 来修饰一个指针变量时,关键字 const 出现在指针的右边表示指针不可修改,即不能再指向其它数据;如果出现在指针的左边,表示不能使用解引用该指针来改变数据的值(但可以通过改变指向的变量自己来修改值)。比如 STL 中的 const_iterator 就是一个后者的应用。

int main()
{
    int i(3),j(3),k(3);

    int* const pi1 = &i;
    *pi1 = 4;       //right
    //pi1 = &k;     //error

    int const * pi2 = &j;   //等同于 const int *pi2 = &j;
    pi2 = &k;       //right
    k = 4;          //right
    //*pi2 = 4;     //error
}

不能把 const 变量的地址赋给一个 non-const 指针。

改善 C++ 程序效率的一个根本办法是使用 pass-by-reference-to-const 方式来传递对象,而此技术的前提是,我们有 const 成员函数来处理取得的 const 对象。

成员函数有没有用 const 来修饰,可以被重载,这是一个很重要的 C++ 特性。

4、确定对象使用之前已经初始化

 略

6、若不想使用编译器自动生成的函数,就该明确拒绝

比如说 boost::noncopyable 的实现:

  class noncopyable
  {
   protected:
      noncopyable() {}
      ~noncopyable() {}
   private:  // emphasize the following members are private
      noncopyable( const noncopyable& );
      const noncopyable& operator=( const noncopyable& );
  };

拒绝自动生成的函数,可以使用 private 访问修饰符,只声明而不定义即可,或者使用 c++0x 的 delete 关键字更明确。

9、绝不在构造和析构函数过程中调用 virtual 函数

直接通过子类创建子类对象时,会先调用基类构造函数,再调用子类构造函数;销毁子类对象时,会先调用子类析构函数,再调用基类析构函数。

通过基类对象指针创建子类对象,delete 基类对象指针时,只有基类析构函数是 virtual 的,才会先调用子类析构函数,然后再调用基类析构函数。

所以基类构造函数里,不能企图调用 virtual 成员函数实现多态功能,因为此时子类构造函数尚未调用;同样的,基类析构函数里也一样,因为此时子类对象已经先析构了。

13、以对象管理资源

14、在资源管理类中小心 copying 行为

15、在资源管理类中提供对原始资源的访问

17、以独立语句将 newed 对象置入智能指针

18、让接口容易被正确使用,不易被误用

19、设计 class 犹如设计 type

20、宁以 pass-by-reference-to-const 替换 pass-by-value

23、宁以 non-member、non-friend 替换 member 函数

24、若所有参数皆需类型转换,请为此采用 non-member 函数

25、考虑写出一个不抛异常的 swap 函数

27、尽量少做转型

28、避免返回 handles 指向对象内部成分

29、为"异常安全"而努力是值得的

30、透彻了解 inlining 的里里外外

31、将文件间的编译依存关系降至最低

40、明智而审慎的使用多重继承

41、了解隐式接口和编译期多态

42、了解 typename 的双重意义

43、学习处理模板化基类内的名称

44、将与参数无关的代码抽离 templates

45、运用成员函数模板接受所有兼容类型

46、需要类型转换时请为模板定义非成员函数

47、请使用 traits classes 表现类型信息

48、认识 template 元编程

49、了解 new-handler 的行为

50、了解 new 和 delete 的合理替换时机

51、编写 new 和 delete 时需固守常规

52、写了 placement new 也要写 placement delete

原文地址:https://www.cnblogs.com/tianyajuanke/p/3213830.html