罗剑锋的C++实战笔记
罗剑锋
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
4051 人已学习
课程目录
已完结 30 讲
0/4登录后,你可以任选4讲全文学习。
课前导读 (2讲)
开篇词 | 把C++从“神坛”上拉下来,这次咱这么学
免费
课前准备 | 搭建实验环境
概论 (5讲)
01 | 重新认识C++:生命周期和编程范式
02 | 编码阶段能做什么:秀出好的code style
03 | 预处理阶段能做什么:宏定义和条件编译
04 | 编译阶段能做什么:属性和静态断言
05 | 面向对象编程:怎样才能写出一个“好”的类?
语言特性 (5讲)
06 | auto/decltype:为什么要有自动类型推导?
07 | const/volatile/mutable:常量/变量究竟是怎么回事?
08 | smart_ptr:智能指针到底“智能”在哪里?
09 | exception:怎样才能用好异常?
10 | lambda:函数式编程带来了什么?
标准库 (4讲)
11 | 一枝独秀的字符串:C++也能处理文本?
12 | 三分天下的容器:恰当选择,事半功倍
13 | 五花八门的算法:不要再手写for循环了
14 | 十面埋伏的并发:多线程真的很难吗?
技能进阶 (4讲)
15 | 序列化:简单通用的数据交换格式有哪些?
16 | 网络通信:我不想写原生Socket
17 | 脚本语言:搭建高性能的混合系统
18 | 性能分析:找出程序的瓶颈
总结篇 (5讲)
19 | 设计模式(上):C++与设计模式有啥关系?
20 | 设计模式(下):C++是怎么应用设计模式的?
21 | 知识串讲(上):带你开发一个书店应用
22 | 知识串讲(下):带你开发一个书店应用
期末测试 | 这些C++核心知识,你都掌握了吗?
结束语 (1讲)
结束语 | 路远,未有穷期
轻松话题 (4讲)
轻松话题(一) | 4本值得一读再读的经典好书
轻松话题(二) | 给你分享我的工作百宝箱
轻松话题(三) | 提高生活质量的App
轻松话题(四) | 真正高效的生活,是张弛有度
罗剑锋的C++实战笔记
15
15
1.0x
00:00/00:00
登录|注册

22 | 知识串讲(下):带你开发一个书店应用

罗剑锋 2020-06-25
你好,我是 Chrono。
在上节课里,我给出了一个书店程序的例子,讲了项目设计、类图和自旋锁、Lua 配置文件解析等工具类,搭建出了应用的底层基础。
今天,我接着讲剩下的主要业务逻辑部分,也就是数据的表示与统计,还有数据的接收和发送主循环,最终开发出完整的应用程序。
这里我再贴一下项目的 UML 图,希望给你提个醒。借助图形,我们往往能够更好地把握程序的总体结构。
图中间标注为绿色的两个类 SalesData、Summary 和两个 lambda 表达式 recv_cycle、log_cycle 是今天这节课的主要内容,实现了书店程序的核心业务逻辑,所以需要你重点关注它。

数据定义

首先,我们来看一下怎么表示书本的销售记录。这里用的是 SalesData 类,它是书店程序数据统计的基础。
如果是实际的项目,SalesData 会很复杂,因为一本书的相关信息有很多。但是,我们的这个例子只是演示,所以就简化了一些,基本的成员只有三个:ID 号、销售册数和销售金额。
上节课,在讲自旋锁、配置文件等类时,我只是重点说了说代码内部逻辑,没有完整地细说,到底该怎么应用前面讲过的那些 C++ 编码准则。
那么,这次在定义 SalesData 类的时候,我就集中归纳一下。这些都是我写 C++ 代码时的“惯用法”,你也可以在自己的代码里应用它们,让代码更可读可维护:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《罗剑锋的C++实战笔记》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥19.9
立即订阅
登录 后留言

精选留言(7)

  • robonix
    代码里显式声明了转移构造和转移赋值函数,这样,在放入容器的时候就避免了拷贝,能提高运行效率。
    那么被转移的类会被掏空了,使得内部数据无效吗?

    作者回复: 需要理解转移语义,它的目的就是要把原对象的内容给“偷走”,转移到新的对象里。

    这样原对象就空了,但数据依然是有效的,比如0、nullptr,只是没有了实际意义,可以被安全、轻量地销毁。

    2020-06-28
    2
  • robonix
    老师,还想问一下,为啥不用std::lock_guard,自己写一个lock呢,只为了性能嘛?

    作者回复: 示例代码,当然都是自己写出来比较好了,可以实践一下编码准则。

    2020-06-28
    1
  • 有学识的兔子
    我碰到一个pybind11的问题:代码Client.cpp使用了第三方zmq组件,如果要转化成python可以调用的模块,除了适配Client.cpp自身接口需要用pybind11声明外,zmq涉及到的接口也要做么?
    看转换的格式比较固定,是不是有自动化的工具来做这件事呢?

    作者回复: 可以把zmq的调用封装起来,不对外暴露zmq接口,Python调用只传递几个参数。

    2020-06-26
  • 有学识的兔子
    1、Thread生成的地方,没有去做异常检查,我不太确定需不需要?
    2、假如使用python脚本去简化客户端测试,是不是通过PYBIND11的方式把Client.cpp里的接口转化成python能够加载模块,在利用python测试该模块?
    3.可以将SalesData里面涉及pack和upack的部分拆分出来,用工厂方法进行替换;工厂类可以借用STL将不同类型数据格式和对应工厂类映射起来;在通过配置文件增加该类型的配置,解析到数据类型后,关联到对应的工厂类产生对应的对象,基于此来动态切换实现pack和unpack的数据格式。

    作者回复:
    1.只要没有显式声明noexcept的地方,其实都应该加上try-catch。

    2.对,用C++写底层接口,然后用Python、lua去调用。

    3.思路很对。

    2020-06-26
  • 沉淀的梦想
    为什么不用智能指针 unique_ptr,而是一定要自己重新写一个 SpinLockGuard?

    作者回复: unique_ptr只能管理对象的生命周期,自动销毁堆上的对象。而SpinLockGuard的目的是在生命周期结束时自动解锁。

    虽然用的都是RAII技术,但两者的行为、作用不同。

    2020-06-25
  • LDxy
    课下作业第3应该说的是客户端和服务器端吧

    作者回复: 可以看一下21讲,这个服务器前面是前端服务,不是直接的客户端,当然,说是客户端也可以,毕竟是示例程序,不那么严格。

    2020-06-25
  • 木瓜777
    每次接受请求,都开启一个线程,是否合理?

    作者回复: 每个请求开新线程的代价是比较高的,但课程里的代码只是为了演示目的,实际项目里最好用线程池。

    2020-06-25
    1
收起评论
7
返回
顶部