读书笔记:Effective C++(第三版)
开始记录这本书的阅读笔记出自三个目的:
很多人说没读过Effective C++等于没学C++;
很难坚持以往想法-验证这种模式的学习,实在耗费精力,希望能在读书上仍然坚持下去;
希望这本书能缓解我写代码时对于安全性、规范和技巧上的惶恐不安。
本文的主题以及本书的副标题是改善程序设计的55个条款。值得一提是,本文不是大多数笔记那样的纯摘抄和摹写(实际上这种台湾翻译不太符合内地术语习惯,意义并不大,再者本书在C++
11以前出版,有许多语言特性和解决方案已经落后,在能力范围以内不指出是一种懒惰的阅读习惯。
持续更新。
条款01:View C++ as
a federation of languages.
视C++为一个语言联邦。
C++一开始是一种C with
Classes,但随着语言逐渐成熟,其开始引入各种编程战略,例如Exceptions(异常处理)、Templates(模板)、STL;今日的C++已经是多重范型编程语言(multiparadigm
programming
language),同时支持面向过程、面向对象、函数、泛型(generic) ...
Apply OpenCV In QtCreator:在Qt中使用OpenCV环境
一篇水文,部署没什么难度,环境变量重复包含居然会导致编译通过但无法在QtCreator运行,记录一下。
Qt的OpenCV环境部署
在此前一篇文章OpenCV
C++记录(一):基于MinGW的环境搭建我们使用了mingw通过cmake编译OpenCV
4.5.5,因为勾选了With
QT选项现在可以直接将OpenCV集成到Qt项目,仍然采用cmake管理。
自动关联路径
Qt的cmake可以通过find_package来自动搜索依赖包,我们只需要包含OpenCV的编译路径即可:
1234567891011121314151617181920212223242526272829cmake_minimum_required(VERSION 3.5)project(QtOpenCVtest)set(CMAKE_AUTOMOC ON)find_package(Qt5 COMPONENTS Core # Gui # Widgets REQUIRED)set(OpenCV_DIR "D:/opencv-4.5.5/build/install ...
Qt的Json序列化
Json的易用性使得它成为最常用的通信格式之一,本文记录了Qt中的Json封装和解析,包括QJsonDocument、QJsonObject、QJsonValue、QJsonArray类型;
QJson
直接看示例就会用了,一个示例json: 123456789101112131415{ "Company": "Digia", "From": "1991", "Name": "Qt", "Page": { "Developers": "https://www.qt.io/developers/", "Download": "https://www.qt.io/download/", "Home": "https://www.qt.io/" ...
Mat/QImage To Json:Mat/QImage类型的Json序列化
记录了cv::Mat的json序列化和反序列化过程,以及比对序列化反序列化前后的两个Mat矩阵是否对应。
Mat to json序列化
Mat是一种特殊的数据类型,如果使用vector再进行JsonArray序列化略微繁琐,且类型不同通道数通用性较差,一般习惯使用base64编码图像信息,首先通过cv::imencode函数进行编码(因为大多数图像是8位位深,故该函数仅支持CV_8U类型的编码);
12345678910111213141516bool cv::imencode(const std::string& ext, InputArray img, std::vector<uchar>& buf, const std::vector<int>& params = std::vector<int>())//参数:ext:png或者jpg,前者无损,后者有损;img:输入图像;buf:编码数组;params:png/jpg模式具体参数(可缺省),如: - std::vector<int& ...
(Private)巧思设计:基于任意对象的日志打印设计
103c704d716c2a6b4b59a60c7b698e01e267a92d601a60f130246c8b57cc624a003856e3d418a0f461510530aabe27de357c3c56037bc9ce191314c495c6c1714fbf8efc9b427c0491c5c978a7861b748bdab2c41c43fe1b842056241317123a7fff4bb9e0e27fc9b212a04545d21f4c46a954ab65a678fcb60d640c871be6fe9d83491bc34b2625dd65be1558c7d68907a211232efcbff63266f1bec2426119f26c5d6a55ee3dff2b1ca911ec8ecc05a072f0d36fcb8412d57a876092ed44d4f8d1ea667d82bf10633ad087a98db3eb3354d39ce35f37470d8580c05e12ad0d8de5f3b5a93500db31c6fba0a2cad211fdf110f61f51da50f ...
C++ 14 读写锁
C++读写锁
C++14引入了shared_mutex,允许使用shared_lock来进行并发读取操作,大幅度提高读线程的吞吐量,对于写操作仍然使用unique_lock独占锁维护数据安全,因为读写锁始终是共享一把锁,虽然读线程间没有了竞态条件,但写线程仍然需要和读、写线程同时竞争锁,而且读写锁一般开销大于普通互斥锁。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <iostream>#include <vector>#include <shared_mutex>#include <mutex>#include <thread>#include <functional>#include <chrono>using namespace std;class Person{private ...
Qt Core Application:元对象/属性系统/反射
有限的RTTI
运行时类型信息(Run-Time Type
Info,RTTI)是C++等静态语言的一个重要特性,C++的类型检查基本在编译期完成,仅提供了typeid、dynamic_cast两种用于支持运行时的类型信息,它们在前面的文章介绍过了:typeid用于获取类名,然而在不同的编译平台上这个方法得到的结果并不统一,尤其是gcc、clang等平台,需要进行转换;dynamic_cast常用于避免大指针去操控小内存(例如子类指针去操作父类),这是非安全的下行转换行为;
可见C++对RTTI的支持实在非常有限,而恰巧Qt中对RTTI的需求是较高的,例如一个基类指针Animal*
去保存若干派生类如Monkey* 、
Panda*,一旦编译完成,在已编译信息中就无法区分哪些函数、成员变量是属于哪个类的了,C++
RTTI唯一可以做的是通过上述typeid获取到其类名,而不能特别地访问某些类成员变量或者函数,莫谈如何操作;但同为静态语言的Java、C#等就有强大的RTTI支持,乃至成为其引以为傲的动态特性,这种支持运行时动态创建、访问类型的特性,称为反射(Reflectio ...
C++ 11 线程池
单任务队列线程池
C++
11引入了五个头文件用于支持多线程编程,但是在很多场合下,工作的子任务往往是循环往复的,因此产生了线程池的应用,线程池一个重要的初衷就是希望将线程成池管理起来,由我们去控制它的分配和使用,需要时取出线程分配使用,当线程结束时它能够被重新回到池中复用。在搜寻相关资料时看到一篇通俗易懂的文章,这部分的代码参考自原文,对语法糖不熟悉的可以移步学习。
其基本工作流如下:
积木一:安全队列
安全队列是一个带锁的FIFO结构,用于管理各种任务的出入:
1234567891011121314151617181920212223242526272829303132333435template<typename T>class SafeQueue{private: mutex qlock; queue<T> m_queue;public: SafeQueue(){} SafeQueue(SafeQueue&& otherQueue){} ~Saf ...
Qt TCP Socket与WebSocket
网络通信是Qt框架的常见应用,本文以TCP和WebSocket为例介绍了二者实现信息收发的基本方法和细节,可以作为初始开发的基本demo,采用cmake方法管理基本文件依赖关系,本文暂不涉及界面开发部分,直接基于QObject而不是QWidget。
前置环境说明
在Linux环境下进行网络通信实验是比较方便的,Windows下则需要一些步骤去适配动态库差异,本文兼顾了两个系统运行,所以某些步骤对Linux环境可能是多余的,本文采用mingw来编译工程,应该提前检查环境变量,并且在Qt Creator-帮助-关于插件-搜索cmake勾选"load"。
Ubuntu防火墙检查
首次使用某端口进行通信时,常常需要打开防火墙,windows会有弹窗提示,点击允许即可,linux则使用ufw检查:
1234567891011sudo ufw statussudo ufw allow 8887 #开放端口sudo ufw enable #启动防火墙sudo ufw reload #重新加载规则sudo ufw status #端口已经更新## 其余规则sudo ufw delete al ...
设计模式(三):简单工厂模式、工厂模式、抽象工厂模式
简单工厂模式
简单工厂模式的设计是当我们需要各种各样的产品时,只需要在工厂新建一条产线,让工厂进行产品供给,而无需用户侧关心产品的制作细节,仅需要根据类型向工厂下订单即可。换到程序设计的语言,也即用户需要不同的产品类,这些产品类都具有相同功能、特性不同的接口,仅需要向工厂类提供类型,由工厂类进行分配,对工厂类而言,也不过是多了一个case去包含这个产品,实现了类间的松耦合。
简单工厂模式的角色为几类:
抽象产品类:相当于提供给工厂统一接口,具体特性接口由产品自身override;
具体产品类:提供不同的类特性和接口;
唯一工厂类:工厂类负责生产各种各样的产品;
由描述可知C++ 虚函数多态可以完成实现,以下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#include <iostream>using name ...