• 【读书笔记】【More Effective C++】基础议题(Basics)


    条款 1:仔细区分 pointers 和 references

    • pointers 和 references 的区别:
      1. 指针可以赋为空,但引用不可以。【好处:可以认为引用比指针更安全,因为引用不需要检测有效性,其默认不为空】
      2. 指针可以不初始化,但引用必须有初值。
      3. 指针可以重新赋值,但引用初始化后不可以再重新赋值。
    • 总结:
      • 使用指针的场合:一是存在不指向任何对象的可能性;二是需要能够在不同的时刻指向不同的对象。
      • 使用引用的场合:总是指向一个对象且一旦指向一个对象之后就不会改变指向;重载某个操作符时(作为返回值)。【引用常用于函数的传参和返回】
    • 补充:
      1. 指针有自己的实际地址和所占空间的大小;但引用只是被绑定对象的一个别称,引用和它绑定的变量共享一个地址。
        • 看了一些关于 C++ 引用底层实现的讨论,大部分都指出引用可以理解为 const 指针,但是引用不能仅仅视为指针的语法糖,具体看下面的参考内容。
      2. 指针可以指向指针的指针,甚至更多层的指针;但引用只能有一层。
      3. 指针可以由 const 修饰;但引用不可以由 const 修饰。
      4. 指针可以与数组结合;但引用不可以,没有引用数组这种说法。
    • 参考内容:

    条款 2:最好使用 C++ 转型操作符

    • static_cast(常规类型转换):
      1. 和 C 风格转型的限制一样:不能把 struct 转换成 int 类型,或者把 double 类型转换成指针类型;
      2. 它不能从表达式中去除 const 属性。
    • const_cast(去常量转换):
      • 用来改变表达式中的常量性(constness)或变易性(volatileness)。
        • 但是不能用它来完成修改这两个属性之外的事情。
    • dynamic_cast(继承转换):
      1. 用来执行继承体系中“安全向下转型跨系转型动作”。
        • 安全指的就是由 base 类转向 derived 类或转向 sibling base 类。
        • 失败的转换将返回空指针或者抛出异常。
      2. 想要使用 dynamic_cast ,基类中必须有虚函数。也就是必须要涉及继承机制。
        • 原因是:存在虚函数,说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。
        • 由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。
    • reinterpret_cast(函数指针转换):
      • 最常用的用途是转换函数指针类型,即将函数指针转换成另一种函数指针。
      • 其与编译平台有关,因而不具有移植性。

    条款 3:绝对不要以多态(polymorphically)方式处理数组

    • 多态是继承带来的特性:通过指向基类对象的指针或引用操作派生类对象
    • 多态和指针算法不能混合在一起使用(比如 iter+i 的操作在多态中是难以保证正确的),所以数组和多态也不能用在一起。
      • 数组中各元素的内存地址是数组的起始地址加上之前各个元素的大小得到的,如果各元素大小不一(当实现多态时,动态绑定类型的不同会导致编译器认定的数组元素大小和真实的不一致),那么编译器将不能正确地定位元素,从而产生错误。

    条款 4:非必要不提供 default constructor

    • 默认(缺省)构造函数指的是在没有任何外来信息的情况下将对象初始化。
    • 没有缺省构造函数的类使用起来会有所限制:
      • 无法产生对应的数组(因为一般来说无法在建立对象数组时给构造函数传递参数)。
        • 避免该限制的三种方法:
          1. 在堆栈中创建数组,并且使用有参构造函数。
          2. 使用指针数组,而非对象数组。【new 操作得来的指针如果不进行对应 delete 的操作,会造成资源泄露】
          3. 使用内存池,使用 operator new[] 函数预先申请一块内存,要使用的时候再使用 placement new(定位 new)依次构造。
      • 无法在许多基于模板的容器类里使用(模板内部的实现往往与数组有关)。
      • 假若虚基类没有默认构造函数,那么所有继承类都要保证提供虚基类的构造参数,这是很麻烦的一件事。
    • 但认为“所有类都应该提供默认构造函数”这种观点也是错误的:
      • 提供无意义的缺省构造函数也会影响类的工作效率。
      • 因此如果缺省构造函数无意义的话,尽量避免使用它们。
  • 相关阅读:
    java基于springboot+vue在线考试系统39n99
    【LeetCode】数组系列-双指针
    Kibana配置ES集群
    js逆向tips-某思录登录
    Linux-基础知识(黑马学习笔记)
    vue-cli vue3
    【Leetcode】1573. Number of Ways to Split a String
    inner join与left join之间的区别
    奇舞周刊第495期:软件高可用实践那些事
    概率论得学习整理--番外3:二项式定理和 二项式系数
  • 原文地址:https://blog.csdn.net/weixin_44705592/article/details/126395563