C++知识体系总结:语言核心与代码工程

腾讯技术工程 发表于 8月以前  | 总阅读数:263 次

梳理一下C++的知识体系,温故而知新。文章很长,建议收藏。

写在前面

C++的主战场

都2023年了,还在说C++,难道不应该多讲讲golang/rust/python吗?其他公司我不知道,但在至少在腾讯内,如果能把C++代码写好,仍然有不错的饭碗,比如游戏/微信后台等。

C++在行业里的主战场,有网友做了一个图,可以看看:

谁在蚕食C++的市场? C++的基本盘虽然很稳,但是我们也能感受到一些明显的趋势:--过去几年招聘的时候,优秀的C++程序员越来越不好招,取而代之的是大量的java/golang/python程序员进入市场。--从2020年开始,腾讯PCG开始搞研效工程,在推出trpcgo框架后,很多团队很快就从C++切换到了golang。

为什么是golang,从下面这篇文章可以一窥端倪,本文从“performance, simplicity, safety, features, scale, and concurrency“等几个方面对Golang和Rust做了对比,可以看看:

C++知识体系

为便于快速复习C++语言,本文梳理了C++的知识体系,针对C++的重点和难点做了细致说明,同时给出了可运行的源代码,笔者一直以为通过源代码来学习知识点,是掌握一门语言最快的方式。

C++知识体系的搭建基于笔者过往的编程经验,而具体的知识点则参考了知乎上很多优秀文章,所有参考文章都附上了对应链接。

关于C++的语言核心:✧ 新特性:使用新特性有助于简化代码,提高编程效率。例如,一个auto关键字,合理使用可以大大降低大脑和手指的负担,大脑不用记住太多东西, 手指也可以少敲很多代码,体会一下这行代码:for(auto &it : vec) { ... } ✧ 面向对象:继承/多态/运算符重载是对象对象的核心特征,IOStream作为官方库标准库,是使用面向对象的典范 ✧ 泛型编程:基于template的编程,可能是C++最强大的地方,这是一种和面向对象完全不同的思维方式,STL是使用泛型编程的典范 ✧ 第三方库:编程语言要想发挥巨大作用,必须依赖第三方库,本文重点在语言内核上,对第三方库不做过多介绍 关于C++工程化:主要涉及代码构建,单元测试,代码调试,编程环境IDE

关于学习方法

作为程序员,编程语言不仅仅是工具,更是饭碗,须勤学苦练,谈几点笔者的看法:

✧ 每隔两三年学习一门新语言,指望一门语言就能包打天下的时代已经过去了,新生语言在不断蚕食既有语言的地盘,要想不被淘汰,就得紧跟趋势。

✧ 笔者都会什么语言?熟练使用能够端上饭碗的语言有C++/Python/Golang/shell;学过一年以上能够把该语言核心教程里的代码全部跑通的有:PHP/Javascrip/html/css;通读过该语言核心教程并理解其核心思维的有:java/perl/ruby。

✧ 程序员之上是架构师,有扎实编程功底,有良好代码品味的架构师才是货真价实的,否则就是花架子,talk is cheap。

教学相长,在谈谈笔者对教学方法与学习方法的体会:

✧ 关于教学方法:工作多年的资深开发,一般都要承担传道授业解惑的职责,作为他人导师,通常技术能力和知识结构都没有太大问题,但可以有意识地修炼一下自己的教学方法。headfirst系列的书籍,笔者看过几本,就教学方法而言绝对是上乘之作。

✧ 关于学习方法:在精通一门语言的情况下,如何快速学习一门新语言?在笔者看过的众多编程书籍里面,《PHP&MySQL 范例精解——创建/修改/复用》这本书明确提出了一个非常有效的方法:找到工业级代码范例,然后“Create-Modify-Reuse”,这是笔者认为最好的学习方法,代码是最好的老师。

1. C++新特性(常用)

C++11是C++发展的一个分水岭,从此C++进入了所谓的“现代C++”阶段,往后C++14/17/20持续发展。

在腾讯内部,C++的主战场,比如微信后台/游戏后台,笔者咨询过相关部门的资深C++开发同学,除了一些历史遗留代码,新系统的开发一般都用现代C++。

就C++具体版本而言,在生产环境中主要还是C++11,例如在微信后台生产环境中gcc的版本是:gcc version 7.5.0 (GCC) ,笔者所在部门腾讯视频,云开发机默认是gcc (GCC) 4.8.5 (Red Hat 4.8.5-39)(注:截止2023.7)。

这一节对C++常用的新特性做简明扼要的介绍:

参考:

https://www.zhihu.com/pub/reader/120162226/chapter/1354802170299080704

1.1. auto&decltype

auto:变量类型推断 decltype:表达式类型推断

参考:https://zhuanlan.zhihu.com/p/137662774

1.2. for range

基于范围的for循环:

1.3. function&bind&lambda

std::function 快速创建一个函数对象

std::bindbind:绑定函数参数

lambda 匿名函数lamdba:创建匿名函数

代码示例:使用lambda与不使用lambda的比较:

参考:

c++11新特性之std::function和lambda表达式:

https://zhuanlan.zhihu.com/p/137884434

1.4. smart pointer

C++11标准在充分借鉴和吸收了boost库中智能指针的设计思想,引入了三种类型的智能指针,即 std::unique_ptr、std::shared_ptr和 std::weak_ptr1)std::unique_ptr

std::unique_ptr sp = std::make_unique(123);

std::unique_ptr禁止复制语义,为了达到这个效果, std::unique_ptr类的拷贝构造函数和赋值运算符(operator=)被标记为delete。

2)std::shared_ptr

std::shared_ptr sp = std::make_shared(123);

3) std::weak_ptr

代码实例:

参考:c++是否应避免使用普通指针,而使用智能指针(包括shared,unique,weak)?

https://www .zhihu.com/question/319277442/answer/1517987598

代码示例:使用auto_ptr时,拷贝或复值导致p1 持有的堆对象被转移给 sp2:

unique_ptr:

shared_ptr:

1.5. explicit与default与delete

explicit:只能显示构造,禁止隐式构造 (例如,允许A a(1); 但禁止A a = 1 ) default : 声明构造函数为默认构造函数(有了=default,就不用显式定义函数体了) delete : 禁止对象的拷贝与赋值 delele函数在c++11中很常用,std::unique_ptr就是通过delete修饰来禁止对象的拷贝的。

代码示例:

代码示例2:

1.6. 右值引用与移动构造函数

本节参考:

程序喵大人:左值引用、右值引用、移动语义、完美转发,你知道的不知道的都在这里

作用:右值引用与std::move结合,减少对象拷贝

附:move函数实现

1.7. 委托构造与继承构造

1.8. random

参考:https://www.jianshu.com/p/05863a00af8d

代码示例:https://github.com/lxn7022/learn-and-practice/blob/master/c%2B%2B/container/use-vector.cpp

1.9. to_string()

参考:https://blog.csdn.net/lzuacm/article/details/52704931

1.10. cstdint

参考:https://en.cppreference.com/w/cpp/header/cstdint

1.11. 新特性系统梳理

下面这篇文章对c++各个版本的新特性有系统梳理,用思维导图呈现,很详细:

知识点列举,含代码:https://zhuanlan.zhihu.com/p/139515439

2. 面向对象

2.1. 对象创建与内存管理

  • new和malloc的区别:

  • delete与delete[]delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。在More Effective C++中有更为详细的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operator delete来释放内存。” delete与new配套,delete []与new []配套

  • volatile 与 mutable

volatile:表明所修饰的变量是易变的,例如多线程并发场景,加上voltile用于禁止编译器对变量做优化

mutable:作用同volitile,只是mutable只能用于类成员函数。

参考:https://zhuanlan.zhihu.com/p/571017611

代码示例下面这个代码例子,综合展示了前面介绍的各个关键字的使用:

代码地址:https://github.com/lxn7022/learn-and-practice/tree/master/c%2B%2B/ringbuffer/v1

2.2. 多继承与内存布局

简单非多态

  • 虚函数+静态数据成员

  • 单继承对象的内存布局

  • 多重继承+虚函数

  • 虚继承内存布局

参考:https://zhuanlan.zhihu.com/p/438006262

2.3. 虚函数与纯虚函数

虚函数

  • ✓纯虚函数

参考:https://zhuanlan.zhihu.com/p/37331092

✓纯虚函数,代码示例:

2.4. 运算符重载(C++面向对象精华)

知识点梳理

  • 代码示例

代码:https://github.com/lxn7022/learn-and-practice/tree/master/c%2B%2B/overload

参考: https://www .cnblogs.com/wanghongyang/p/15014326.html

2.5. 访问控制

访问控制

  • ✓继承控制**注意:默认是private继承,所以通常都要指定public继**

参考:https://zhuanlan.zhihu.com/p/107709327

  • ✓friend函数
  • 友元函数可以访问当前类中的所有成员,包括 public、protected、private 属性的。
  • 可以将非成员函数声明为友元函数
  • 可以将其他类的成员函数声明为友元函数

✓非成员函数的例子:

成员函数的例子:

提示:可以将友元函数的函数体放在class内,隐式inline

  • ✓friend类

不仅可以将一个函数声明为一个类的“朋友”,还可以将整个类声明为另一个类的“朋友”,这就是友元类。

友元类中的所有成员函数都是另外一个类的友元函数。

参考:http://c.biancheng.net/view/2233.html

代码:https://github.com/lxn7022/lear

3. template 模板

3.1. 函数模板

代码示例:

参考:https://zhuanlan.zhihu.com/p/381299879 https://zhuanlan.zhihu.com/p/101898043

3.2. 类模板

代码示例:

参考:https://zhuanlan.zhihu.com/p/381299879 https://zhuanlan.zhihu.com/p/101898043

3.3. 可变参数

基本概念:

  • 参数包:在函数原型的声明中Args... args同理存在0个或者一个1以上的类型参数,C++中将“typename... Args”这样的语义,称为参数包 (parameter pack)。
  • 包展开:参数包只有在使用时就必須把它展开变成一个个的参数,概念上称为**包展开(pack expansion)**,将参数包当作普通的参数一样放到被调用函数的参数列表的最后一个位置,并在后面加上 ...

参考:https://zhuanlan.zhihu.com/p/490470765

代码示例:

通过一个简单示例,理解函数模版中可变参数的作用:

代码示例2:

3.4. typename与class

通常两者是等价的:

有一些场景只能使用typename

参考:https://zhuanlan.zhihu.com/p/335777990

3.5. STL中的模板

  • 泛型编程,C++最强大的地方,也是最复杂的地方
  • 基于模版的编程,主要用于程序库的编写,例如STL

3.6. 元编程

关于元编程,主要用于编写程序库,实际工程使用较少:

参考:https://zhuanlan.zhihu.com/p/13

4. STL (泛型编程典范)

4.1. 容器 Container

整体梳理

序列容器:【array vector】 【queue deque priority_queue stack】 【list forward_list】

关联容器:map set || multimap multiset

关联容器:unordered_map unordered_set || unordered_multimap unordered_multiset

  • 参考下面这个资料,每个容器介绍一遍,根据官方文档整理,简明扼要:

https://zhuanlan.zhihu.com/p/542115773

  • [C++ STL] 各容器简单介绍,有代码示例:

https://zhuanlan.zhihu.com/p/130905242

*根据笔者过去十多年的一线开发经验,尽管每种语言都提供了大量的数据结构,但最常用的似乎就两种,例如○ C++里的vector和map,○ Python里的list与dict,○ Golang里的slice与map,*对比以上几种数据结构,这种逻辑上的相似性,似乎揭示了编程语言的某种本质,就像每种编程语言都有循环与控制语句一样。

vector✧ 增删改查操作

参考:C++中STL---vector详解_c++ vector_愚蠢的土拨鼠。的博客-CSDN博客

vector的迭代器

参考:涛哥:STL教程(四):C++ STL常用容器之vector

map

参考:【STL】关联容器之map用法总结_舒泱的博客-CSDN博客

以下是map的基本操作:

unordered_map

  • 关于unordered_map, 有非常多函数,参考下面这篇文章:

https://blog.csdn.net/qq_44423388/article/details/126822071

https://blog.csdn.net/qq_44423388/article/details/126822071

  • map与 unordered_map的区别点:

emplace与insert,功能类似,但执行效率更高:

为什么emplace的执行效率更高?

https://zhuanlan.zhihu.com/p/599902005

4.2. 算法 Algorithm

参考下面这篇文章:http://c.biancheng.net/view/7241.html

c++11 新增算法:

4.3. 迭代器 Iterator

4.4. STL使用介绍

参考下面这篇文章:http://c.biancheng.net/view/7241.html

5. IO流(面向对象典范)

5.1. iostream

技术原理:

代码示例:

代码:https://github.com/lxn7022/learn-and-practice/blob/master/c%2B%2B/stream/use-iostream.cpp

5.2. fstream

代码示例:

https://github.com/lxn7022/learn-and-practice/blob/master/c%2B%2B/stream/use-fstream.cpp

5.3. stringstream

知识点梳理:

代码示例:

https://github.com/lxn7022/learn-and-practice/blob/master/c%2B%2B/stream/use-sstream.cpp

5.4. strstream

  • 知识点梳理

参考:https://zhuanlan.zhihu.com/p/123177742

代码示例:

6. 代码构建

6.1. 选择什么工具

参考:靖哥哥吃糖:C++编译之make cmake bazel模板

几种构建工具的对比,可以参考:如何评价 Google 开源的 Bazel ?

6.2. make与Makefile

在腾讯公司内部,系统架构从整体上来说,基本都是微服务模式,即很多小模块以rpc的方式构成一个大的分布式系统,每个模块的规模都不是很大,因此C++开发一般都用make来编译和构建。下面是笔者使用的一个Makefile模版:

6.3. cmake与CMakeLists.txt

CMakeLists.txt主要通过函数的方式来组织编译规则,下面是一个示例文件:

6.4. bazel与BUILD

从2018开始,腾讯的研发体系发生了巨大变革,从以往的DO分离逐步变成了CI/CD,传统的运维消失了。反映在C++开发上,版本管理从svn切换到了git,构建工具逐步从make逐步切换到了bazel。另一方面,过去C++坚固的阵地发生了松动,golang以其简单和高性能在逐步蚕食C++的地盘。

下面是bazel配置文件的写法,相比make和cmake更可读:

6.5. 腾讯的工程实践

在腾讯内部,代码管理经历了不同阶段,不同部门也有不同的代码管理规范,下面这篇文章介绍的内容很有代表性:

文章地址:腾讯技术工程:微信小仓实践录|后端代码仓库发展史

7. 单元测试

写好单元测试,让代码时刻处于可运行状态,代码只有跑起来才叫代码,跑不起来的那叫伪代码。

7.1. 单测概念

7.2. 单测框架

Google Test官方文档:

入门: https://github.com/google/googletest/blob/master/docs/primer.md

进阶: https://github.com/google/googletest/blob/master/googletest/docs/advanced.md

Google Mock官方文档:

入门: https://github.com/google/googletest/blob/master/googlemock/docs/for_dummies.md

进阶: https://github.com/google/googletest/blob/master/googlemock/docs/cheat_sheet.md

https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md

7.3. 单测实战

详细内容参考,【金山文档】 CPP单元测试实战:

https://kdocs.cn/l/ctiKaoV1hX3j

8. 代码调试

8.1. gdb

调试C/C++代码,最著名的工具就是gdb,但坦白说笔者用的并不多, 在过往十多年的编程生涯里,用gdb的次数不会超过十次:)

常用的 gdb 命令:

参考:大佬们都是怎么用gdb的?或者用吗?

8.2. 通用方法

不用gdb并不代表不调试代码,笔者总结了调试代码的三板斧:print+log+unittest 大部分时候就用print,用不了print就打log,近几年体会到了单测的威力,就开始写单测 调试代码的三板斧,不光适用于C/C++,其他编程语言例如python/golang/shell等,都统一适用 这三板斧,平淡无奇人人都会,没有gdb的逼格,但用好了基本可以解决99%的问题,不low!

9. 工具链IDE

9.1. Vscode上配置C++11环境

配置过程

vscode配置选项

配置文件:

"-std=c++11", "-stdlib=libstdc++", "-Wc++11-extensions",

9.2. Git与Github

代码管理,不管是在公司内部还是在社区,现在一般都用Git。常用命令请参考:

✧ 靠代码吃饭的人,建议开通自己的github账号 ✧ 没事的时候就码几行代码,时刻保持良好的技术状态:

9.3. Vim

写代码这个事情,一练脑子,二练手指。学会vim,形成肌肉记忆,自然能体会到其妙处

在linux环境下,经常用vim对文本文件做一些简单的增删改查编辑操作,老司机一般都会用, 建议新手做简单学习:

本文由微信公众号腾讯技术工程原创,哈喽比特收录。
文章来源:https://mp.weixin.qq.com/s/lQoH4UF36_zKrw-Jbp2ylw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:8月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:8月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:8月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:8月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:8月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:8月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:8月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:8月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:8月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:8月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:8月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:8月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:8月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:8月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:8月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:8月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:8月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:8月以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  236913次阅读
vscode超好用的代码书签插件Bookmarks 1年以前  |  7118次阅读
 目录