由于是初学c++,在看这份指南时,很多地方的一些专业术语并不是很清楚,所以每一块的笔记最前面都会有一个概念梳理,方便阅读时自己遗忘了某一概念,能够第一时间找到对应的答案。
一、头文件
1.头文件中的概念梳理
①.h是头文件,用于定义函数等
②.inc用于插入文本的文件
③ 前置声明是类、函数和模板的纯粹声明,没伴随着其定义。
④ 头文件的次序:优先位置;C系统文件;C++系统文件;其他库的.h文件;本项目内.h文件
2.Google不再把模板或内联函数的定义放到分离的-inl.h文件里
3.应该使用#define来防止头文件被多重包含,保证头文件只被编译一次
【命名格式是:项目名_路径_文件名_H_】
例如:#define FOO_BAR_BAZ_H_ (该头文件位于项目foo中foo/src/bar/baz.h)
4.尽可能使用#include包含需要的头文件,避免使用前置声明。
5.只有当函数体较小且不含循环或switch语句时才将其定义为内联函数
6.在#include中的各头文件之间插入空行,C库,C++库,其他库的.h和本项目内的.h,使头文件的内容和编译顺序一目了然
二、作用域
1.作用域中的概念梳理
①匿名命名空间:当定义一个命名空间时,可以忽略这个命名空间的名称,编译器在内部会为这个命名空间生成一个唯一的名字,而其作用域被限制在当前文件中。
②内联命名空间:命名空间中的名称同时是外层命名空间直接包含的名称。内联命名空间主要用来保持跨版本的 ABI 兼容性。
③污染命名空间:符号命名没有层次,不同模块间名字相互冲突的概率很高
④using指示:using指示使得特定命名空间的所有名字可见,从using指示点开始对名字可以不加限定符使用,直到包含using指示的作用域的末尾;using指示具有将命名空间成员提升到包含命名空间本身和using指示的最近作用域的效果
⑤using声明:一个using声明一次只能引入一个命名空间成员,从using声明点开始,直到包含该using声明的作用域结尾,声明的名字仅仅在该作用域是可见的,外部作用域中相同的名字被屏蔽
2. 不要在头文件中使用匿名命名空间,防止多次定义
3. 在循环作用域外面声明构造函数和析构函数,防止每次进入或退出作用域都要调用其函数,导致效率降低
4. 同一个编译单元内,静态初始化优先于动态初始化,初始化顺序按照声明顺序进行,销毁则逆序进行
三、类
1.类中的概念梳理
①虚函数:通过基类访问派生类定义的函数,实现多态
②init():init即initialize,初始化的意思。就是对声明的变量或对象、结构体等进行赋初始值的操作
③explicit关键字:只能用于类内部的构造函数声明上,防止隐式类型转换
④API:应用程序编程接口,是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
⑤接口继承,就是派生类只继承函数的接口,也就是声明;而实现继承,就是派生类同时继承函数的接口和实现。
⑥非虚函数:一般成员函数,无virtual关键字修饰
⑦纯接口:只有纯虚函数(“=0”)和静态函数;没有非静态数据成员;没有定义任何构造函数,如果有,也不能带有参数,并且必须为 protected;如果它是一个子类,也只能从满足上述条件并以 Interface 为后缀的类继承
2.构造函数中不允许调用虚函数
3.仅当只有数据成员时使用struct,其它时候一概使用class
4.类和结构体的成员变量使用不同的命名规则:类数据成员可以和普通变量一样, 但要接下划线;结构体数据成员也可以和普通变量一样, 不用像类那样接下划线
5.所有继承必须是public的
6.将所有数据成员声明为private,除非是static const类型成员
7.尽量不重载操作符、模板,防止过于复杂
8.声明次序: public-> protected -> private
四、函数
1.函数中的概念梳理
①Const:C++中的常类型,常类型的变量或对象的值是不能被修改的
②vector:一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector是一个能够存放任意类型的动态数组,能够增加和压缩数据
③auto:自动类型推断,用于从初始化表达式中推断出变量的数据类型;返回值占位。
2.函数的参数顺序为:输入参数在先,后跟输出参数
3.所有引用传递的参数必须加上const
4.只能在非虚函数中使用缺省参数,且缺省参数的值必须始终一致
五、来自Google的奇技
1.概念梳理
①所有权是一种登记/管理动态内存和其它资源的技术
②智能指针是一个通过重载*和->运算符以表现得如指针一样的类
③cpplint.py是一个用来分析源文件,能检查出多种风格错误的工具
2.std::unique_ptr是C++11新推出的一种智能指针类型。当std::unique_ptr离开作用域时,对象就会被销毁。std::shared_ptr表示动态分配对象的所有权, 可以被共享, 也可以被复制;对象的所有权由所有复制者共同拥有,最后一个复制者被销毁时,对象也会随着被销毁
六、其他 C++ 特性
1.概念梳理
①移动构造函数:使用类的右值引用进行构造的函数
②变长数组:在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组
③constexpr:用来定义真正的常量,或实现常量初始化,constexpr变量必须在编译时进行初始化
2.构造函数与赋值运算符的区别是,构造函数在创建或初始化对象的时候调用,而赋值运算符在更新一个对象的值时调用。
3.使用C++的类型转换,如static_cast<>(),不要使用int y = (int)x或int y = int(x)等转换方式
4.对于迭代器和其他模板对象使用前缀形式(++i)的自增,自减运算符
5.auto只能用在局部变量里用。别用在文件作用域变量,命名空间作用域变量和类数据成员里
6.把自带缺省参数的函数地址赋值给指针时,会丢失缺省参数信息
7.friend实际上只对函数/类赋予了对其所在类的访问权限,并不是有效的声明语句,友元函数不是类的一部分
七、命名约定
1.文件名要全部小写,最好包含下划线(_) 或连字符 (-),例:my_useful_class.cc
2.类型名称的每个单词首字母均大写,不包含下划线:MyExcitingClass
3.变量 (包括函数参数) 和数据成员名一律小写,单词之间用下划线连接。类的成员变量以下划线结尾,但结构体的就不用,如:a_local_variable,a_struct_data_member,a_class_data_member_
4.声明为constexpr或const的变量,或在程序运行期间其值始终保持不变的,命名时以“k” 开头,大小写混合
5.常规函数使用大小写混合,取值和设值函数则要求与变量名匹配:MyExcitingFunction()
体会:
在阅读google c++ style guide后,第一感觉是条理清晰,里面罗列出来的编程规范使得阅读代码变得轻松多了。但是在本次阅读过程中,遇到了一些困难,就是作为c++的初学者,对一些基础概念掌握得仍不够清楚,导致在阅读过程中不得不不断查阅某些c++中的常用概念,使得阅读进度很慢很艰难;而且初次阅读,缺少实际操作,难免有些理解不够深入。希望自己在之后深入掌握了c++这门语言以后,再来阅读一遍这篇指南,再结合实际的编程练习,应该会更有收获的。
网友评论