1. 让自己习惯cpp

小结

  1. 本章是站在全局角度来看待的cpp,介绍了cpp是一个语言联邦,特性可能由于次语言不同而不同
  2. 尽量使用编译器而不是预处理器,使用constexpr、const、enum、inline来替代#define
  3. 确定对象被使用前已经被初始化,且注意non-local static多编译单元初始化顺序不确定性

条款 01:视 C++为一个语言联邦

  1. cpp内部包含四个次语言,c、object c++(也就是面向对象那一套)、template c++(泛型编程、模板元编程)以及STL
  2. 每个次语言的规则以及特性有所不同,比如c中内置类型pass-by-value比pass-by-reference更高效
  1. 所以并不是pass-by-reference永远是最优的,因为如果是传递的reference,就会涉及到一步"解引用",每次读取需要去解引用读取真实值,而对于"轻对象",直接传递值,操作就是直接对数据操作,且可能因为是在栈上而使用缓存加速机制

  2. 适合pass-by-value的情况:

  • 不希望形态的改变影响实参

  • 传递的是"轻对象",复制成本 ≤ 指针大小(如 intdouble迭代器空函数对象

  • 移动语义,就需要使用到移动拷贝构造,所以需要pass-by-value

  • 迭代器,因为逻辑上等价于"指针",所以指针应该是使用pass-by-value;

  1. 不适合pass-by-value的情况:
  • 需要使用多态,如果还是传value,则会出现对象切片

条款 02:尽量以const,enum, inline 替换 #define

define定义常量

  1. 可以使用全局const常变量来代替,如#define PI 3.14 ==> int const Pi = 3.14,是该定义(包括指针常量)是可以出现在头文件的,因为此时变量没有共享性,但是如果又有extern修饰,就具有共享性,不能违反单一定义原则

constexpr是比const更严格的,后者声明的变量如果取地址则不能用来指定数组大小,而前者要求- 必须在编译期就能确定其值,且可用来指定函数,要求该函数在编译期也能调用

  1. 在类中,如果需要#define定义的常量,则可以使用static const int n = 10;来代替,可以不在外面重新定义,此时编译器会把n作为编译时常量来对待,即可用于声明数组个数
  2. enum hack ,一个属于枚举类型的数值可权充int使用,这样可以实现一个专属于某一个类的编译器常量

define定义函数

  1. 即使加上了括号,如果传入i++基本都会出问题
  2. 使用inline+template来替代宏函数

条款 03:尽可能使用const

const与对象

  1. const A a;,对象a直接访问非mutable成员数据修改或调用成员方法修改,都是不行的
  2. 调用的成员方法是const修饰的,否则会报错

const与迭代器

  1. const vector<int>::iterator iter = vec.begin(),声明iter本身是不变的,
  2. const_iterator iter是声明iter指向的对象不可变化

const与函数声明

  1. const与返回值,比如operator*()最好返回const,避免用户代码if((a*b)=c)
  2. const与参数,如果内部不需要修改该参数,尽量使用const修饰

const与成员函数

  1. 原因:外部如果是const声明的对象,调用的方法就是const修饰的,const成员变量是声明不会改变对象内部非mutable数据成员的
  2. 其实const修饰的是参数this
  3. 同时const修饰底层指针,会构成重载,non-const优先调用non-const成员函数,const只能调用const成员函数,也就是成员函数有const修饰会重载
  4. bitwise const是对象占据的内存值不会发生改变,cpp中对于const就是这样想的
  5. logic const 是能修改mutable修饰的成员
  6. 尽量使用non-const调用const成员函数,来减少重复代码

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

  1. c-part-of-cpp 是不会初始化的(比如array),而其他部分是会初始化数据的(比如vector)
  2. 对象数据成员的初始化发生在进入构造函数本体之前,构造函数本体都是赋值
  3. 在初始化列表中列出所有数据成员
  4. static变量是存储在数据区,而不是heap、stack
  5. local static object是指函数中声明定义的static变量,会在程序启动时就在数据区分配空间,初次运行到定义处进行初始化,线程安全
  6. non-local static object,包含全局static、类中static以及命名空间内的static,在main运行前初始化,但是存在跨编译单元初始化顺序不确定问题,解决方案是用local static替换non-local static
相关推荐
故事和你911 天前
洛谷-【图论2-2】最短路4
开发语言·数据结构·c++·算法·动态规划·图论
kyle~1 天前
机器人感知---工业相机硬触发、时间戳同步( PTP)与 ROS2 驱动时间戳设计
linux·c++·机器人·ros2
承渊政道1 天前
【贪心算法】(经典实战应用解析(四):分发饼干、最优除法、跳跃游戏、跳跃游戏Ⅱ、加油站)
数据结构·c++·算法·leetcode·贪心算法·动态规划·哈希算法
历程里程碑1 天前
53 多路转接select
linux·开发语言·数据结构·数据库·c++·sql·排序算法
j7~1 天前
【MYSQL】 mysql库和表的操作--详解
数据库·c++·mysql·数据库表的操作·数据库库的操作
yzqy_1 天前
【c++】智能指针
c++
杜子不疼.1 天前
【C++ AI 大模型接入 SDK】 - LLMProvider 抽象基类与策略模式
开发语言·c++·策略模式
BirdenT1 天前
20260519紫题训练
c++·算法
C+++Python1 天前
C++ 进阶学习完整指南
java·c++·学习
sparEE1 天前
c++值类别、右值引用和移动语义
开发语言·c++