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
相关推荐
阿巴~阿巴~4 小时前
JsonCpp:C++ JSON处理利器
linux·网络·c++·json·tcp·序列化和反序列化
zmzb01035 小时前
C++课后习题训练记录Day38
开发语言·c++
獭.獭.5 小时前
C++ -- STL【string的使用】
c++·string·auto
福尔摩斯张5 小时前
Linux进程间通信(IPC)机制深度解析与实践指南
linux·运维·服务器·数据结构·c++·算法
lijiatu100866 小时前
C++ 类成员变量声明语法错误
java·开发语言·c++
zore_c6 小时前
【C语言】带你层层深入指针——指针详解2
c语言·开发语言·c++·经验分享·笔记
cookies_s_s6 小时前
项目--协程库(C++)前置知识篇
linux·服务器·c++
zmzb01036 小时前
C++课后习题训练记录Day39
数据结构·c++·算法
qq_310658516 小时前
mediasoup源码走读(二)环境搭建与 Demo 运行
服务器·c++·音视频
XiaoCCCcCCccCcccC7 小时前
多路复用 select -- select 的介绍,select 的优缺点,select 版本的 TCP 回显服务器
服务器·c++