[阅读]D&E

立志要把D&E看两三遍,所以这边列一个读书笔记,觉得什么有必要就记下来.

1. 内联

   在带类的C里面,在类声明里面实现的成员函数,可以被内联.

class stack
{
  //会被内联
  char pop()
  {
    if(top <= min) error("stack underflow");
    return *--top;
  }
};

    在C++里面,提供的inline关键字,也可以用来内联.

  另外,static修饰的非成员函数,有internal连接属性,也是可能会被内联掉.

2. 窄转换

  早期想法不允许"破坏信息的"隐式转换.可是后来发现每个C程序内都有大量的int到char的转换.....

  隐式的变窄转换,通常会给warning,除非显式的调用转换.除了int到char...

3. C++里面的保护概念(public/private/protected)

  保护是通过编译时的机制提供,目标是防止发生意外事件,而不是防止欺骗或者有意的侵犯.

  访问权由类本身授予,而不是单方面的取用.

  访问权控制是通过名字实行的,而不依赖于被命名事物的种类.

  保护的单位是类,而不是个别对象.

  受控制的是访问权,而不是可见性.

4. 覆盖和虚函数匹配

class Base
{
public:
   virtual void f();
   virtual void g(int);
};

class Dervided : public Base
{
public:
  void f();        //overrides Base::f()
  void g(char);    //doesn't override Base::g()
};

  非虚函数Dervided::g和Base::g没有任何关系,但是却覆盖了它.这很容易导致出错,编译器没有给任何警告.

5. 基类成员的遮蔽

  派生类里面的名字将遮蔽基类中具有相同名字的任何对象货函数.

6. +=操作符

  +=这一类操作符是更基本的,他们比常规算术的兄弟+等等的效率更高. 最好是先把+=, *=一类的赋值运算符函数定义成成员函数,然后把+,*一类定义成全局函数.

7. const的由来

  C++之父说要有readonly,于是乎标准最后加进去const.但是这边的const,和readonly还是有一点差别,就是语言并没有任何机制去保证这个东西是readonly的.

  还有,全局const变量具有internal链接属性.这是和优化有关的,标准作了假设,就是你不会修改这个const变量,所以不需要在其他单元内连接到同一个对象.

8. 临时变量的生命周期

  临时变量,一定是某一个表达式的子表达式. 当临时变量不再是任何一个表达式的子表达式时,就可以被析构了.

  术语叫,完整表达式的结束.

9.  restrict指针

  restrict指针是用来优化的,主要面向数值计算.如果无特殊需求,可以不用此关键字,否则两个指针的内容有叠加部分,可能会优化出错.

10. 细粒度的重载

  重载会优先匹配准确的类型,匹配不上才会类型提升或者隐式转换.

  另外, 'x'在C++里面是char,在C里面居然是int.

11. 重载的匹配规则

  1) 匹配中不转化或者只是用不可避免的转换,比如,数组名到指针,函数名到函数指针,以及T到const T.

  2) 使用整形类型提升的匹配,ANSI C里面定义的,char到int,short到int,以及他们对应的unsigned类型,以及float到double.

  3) 使用标准转换匹配.例如int到double, dervied*到base*,unsigned int到int等.

  4) 使用了用户定义转换的匹配. 包括构造函数以及转换操作符.

  5) 使用了在函数声明里的省略号...的匹配

  如果存在两个最高的匹配,就是有歧义,便会产生一个编译错误.

12. NonCopyable

  简单的把复制构造函数和赋值函数都定义为私有.

13. 防止派生

  析构函数私有...

  其实C++11有final关键字,也可以用来放置派生

14. 按成员复制

  对象复制被定义为对所有非晶态成员和基类成员的按成员复制.

  如果指针成员按照默认拷贝构造函数和赋值函数复制,就应该给出warning.

15. 前置++,后置++操作符

class Ptr_to_x
{
X& operator++();    //前置
X operator(int);    //后置
};

16. bool类型

  bool是一个特别的整型类型,带有字面量true和false. 非零值可以隐式转化到true, true可以隐式转化到1; 零值可以隐式转化到false, false可以隐式转化到0.

15. 放松覆盖规则

  函数的返回类型,不是需要严格匹配都可以覆盖.

  

class B{
public:
   virtual B* clone() { return new B(*this); } 
};

class D : public B{
public:
   virtual D* clone() { return new D(*this); } //放松返回类型
   void h(); 
};

void gg(B* pb, D* pd)
{
  B* pb1 = pb->clone();
  D* pd1 = pd->clone();
  pd->clone()->h();      
   
  D* pd2 = pb->clone(); //error
  pb->clone()->h();     //error
}

16. protected关键字

  Mark是Interviews的主设计师.他说服老爹在C++里面加入protected.有一万个理由支持这种观点.....

  五年后,Mark在interviews里面禁止使用protected成员,因为他们已经变成许多程序错误的根源....泪奔

17. RTTI的正确使用

  1) 最可取的是根本不用运行时类型信息机制,完全依靠静态类型检查

  2) 如果搞不定, 使用动态转换.

  3) 如果必要的话,使用typeid()做比较.

  4) 如果确实需要知道一个类型的更多信息, 就需要用typeid相关的操作.

/**********************************************************************
 * 机械教条主义
 *
 * From:          http://www.cnblogs.com/egmkang/
 * Email:          egmkang [at] outlook.com
 * Weibo:        http://weibo.com/egmkang
 * Github:       http://github.com/egmkang
 *
 **********************************************************************/

原文地址:https://www.cnblogs.com/egmkang/p/2875953.html