boost库开发笔记(二):boost::asio异步网络编程
boost::asio
boost::asio是C++高级异步网络编程库,主要用于异步编程、调度和通讯,包括定时器、信号处理、异步执行、socket等基本功能。
本文围绕了asio入门的基础、常用接口部件等进行讨论,从简单的asio对象开始,分成异步编程和网络编程两大板块,并且相应地结合源码进行记录。本文会随着项目进展更新,相信会成为比较完备的ASIO入门体系。
boost::asio异步编程
asio::io_context
每个asio程序至少存在一个io_context对象(boost
1.66前称io_service),io_context是asio工作的核心,其提供了一个事件循环队列机制(类似Qt),作为调度器完成事件调度;io_context本身不直接与通信对象通信,而是管理一系列IO资源如定时器、socket等。
asio定时器
asio支持三种定时器,为asio::system_timer、asio::steady_timer和asio::high_resolution_timer,另一种旧版本的deadline_timer已经被弃用;其中:
as ...
C++ 11 新特性总结(四):enable_from_this/shared_from_this
问题起源
问题来自std::shared_ptr,为了保证shared_ptr的计数正确,只允许使用一个智能指针对象去使用裸指针构造,因此这样的代码是错误的:
123Person* p = new Person();std::shared_ptr<Person> p1(p);std::shared_ptr<Person> p2(p);
其后果是p在new时候执行了一次构造,p1和p2都认为自己管理了p,因此两个共享指针独立的控制块都显示引用数为1,所以析构时各自执行一次,导致双重删除:
123Person constructor called!Person destructor called!Person destructor called!
显式上我们不会这么干,但是有一些隐晦的写法还是触碰到这条红线,例如:
123456789101112131415161718192021222324#include <iostream>#include <memory>using namespace std;class Person ...
boost库开发笔记(一):boost::json使用与序列化
boost库
1998年,C++标准委员会创建了boost这个项目,初心是开发可复用的C++组件,为C++发展探索方向,boost早期严格遵循header-only原则,且代码评审规范,一度被称为最美的C++库之一,其次boost中的智能指针、regex、function/bind等一系列开发组件精华被C++标准库吸纳,成为C++事实上的重要参考库。由于boost是完全开源的,它可以前瞻性地完成一些C++开发中需要的组件,在项目上有重要应用成果。
因为项目需要,本系列会逐渐更新boost库的常用接口与原理,并持续更新。
从json方法开始。
boost::json
boost::json::value
基本数据类型构造与转换
object的value和array的成员都是以boost::json::value的形式存储,因此解析时需要重新指定数据类型才能确保类型前后一致,类似QJson的toXXX接口,基本数据类型的boost::json::value支持若干种解析转换方法:as_object、as_array、as_bool、as_double、as_int64、as_ ...
杂记:cmake版本更新/boost编译/ZMQ框架安装
Ubuntu Cmake版本更新
cmake通过bin生效,改变版本时通过软链接指向另一版本即可:
从cmake官网下载cmake-3.29.2.tar.gz,然后解压:
1sudo tar -xvzf cmake-3.29.2.tar.gz
配置编译和安装: 123sudo ./configuresudo make -j8sudo make install
此时cmake --version有可能输出新版本,也有可能保留旧版本,关键是/usr/bin/cmake的版本是什么,这里需要建立一个软链接,不要使用相对路径创建:
12sudo rm /usr/bin/cmakesudo ln -s /home/user/Desktop/cmake-3.29.2/bin/cmake /usr/bin/cmake
ubuntu下boost安装/版本更新
查看版本: 12345#方式1:若是包安装dpkg -S /usr/include/boost/version.hpp#方式2:包安装或源码安装grep "#define BOOST_LIB_VERSION&qu ...
(Private)基于Qt的发布订阅远程过程调用(RPC)网络设计
103c704d716c2a6b4b59a60c7b698e01e267a92d601a60f130246c8b57cc624af198f35b44186f916e87030c3305aea665b698f5705b3810f2c5f71a69ebd180727569d78e7ade3e120b672172d979cd8ffc903f2df6007979cb72c152cc0432e9093b6251aa47d770def05c18f970529dfe9f2b4c050f45dd60ce06dd0a91eed7eea9e622463657842c2d2364264c7051e7a4da4ec4dccc0896189016f74d0a7c60f08b0ad19c9adbceaa855c98591c3b74e871eacaf85be1785ca065d71a716c4900fe5181eb91b453432b2e0775782c8b5669a1c2c757c36b644b70c5bce2a2e7c1d4b4f5f07a0edb918c791b0fc6990eb0ede1335f04a ...
OpenCV C++记录(十一):Mat数据规范化、灰度直方图与均衡算法
归一化
讨论归一化主要是图像数据分析中用到,cv::normalize支持将Mat数据归一化:
123456789void normalize( cv::InputArray src, cv::InputOutputArray dst, double alpha = (1.0), //归一化倍数/下限,根据类型不同而不同; double beta = (0.0), //无意义或归一化上限,根据类型不同而不同,见下文; int norm_type = 4, //默认L2范数,四种方式,cv::NORM_L1/cv::NORM_L2/cv::NORM_INF/cv::NORM_MINMAX int dtype = -1, //输出矩阵类型,-1保持和原矩阵一致 cv::InputArray mask = noArray() //位置掩图,如果对src某区域归一化传入同size的mask(对应roi置白))
这里重要的地方是norm_type对应几种规范化类型,分别是L1范数(平均值)、L2范数、最大值以及范围规范化。 ...
OpenCV C++记录(十):形态学处理基础
形态学处理
在传统图像处理中,形态学处理可算是最为强大的功能之一,只要你稍微有一些粗略的识别-分类需求需要对图像进行前处理,形态学都能帮上大忙,而且具备极高的计算效率。
这得益于其计算原理的简单,腐蚀和膨胀是两种基本操作,注意这里形态学处理的对象都是二值图;
腐蚀与膨胀
腐蚀的基本原理是以二值卷积核和二值图卷积,只要一个位置的相乘结果为0,那么中心像素即为0:
腐蚀基本运算
腐蚀函数原型是: 123456789void erode( cv::InputArray src, //输入二值图像 cv::OutputArray dst, //输出二值图像 cv::InputArray kernel, //卷积核 cv::Point anchor = cv::Point(-1, -1), //处理锚点,默认中心点 int iterations = 1, //腐蚀次数 int borderType = 0, //边值处理:默认常数填充 const cv::Scalar &borderValue = morphologyD ...
OpenCV C++记录(九):二值化与图像模糊(滤波)算法
二值化
全局阈值
将灰度图二值化是图像处理基本操作,比较简单: 1234567double threshold( InputArray src, //输入灰度图 OutputArray dst, //输出二值图 double thresh, //分割阈值 double maxval, //最大阈值,是否生效与类型相关 int type //二值化类型);
二值化类型包括:
THRESH_BINARY:普通二值化,像素大于thresh的设为maxval,其余为0;
THRESH_BINARY_INV:反二值化,像素大于thresh的设为0,其余为maxval;
THRESH_TRUNC:截断二值化,像素大于thresh设置为thresh,其余不变;
THRESH_TOZERO:零二值化,像素大于thresh则不变,其余为0;
THRESH_TOZERO_INV:反的零二值化,像素大于thresh设置为0,其余不变;
THRESH_OTSU:大津法,适用于双峰图像;
...
C++ Generic Programming:SFINAF与类型萃取
SFINAE
SFINAE(Substitution Failure IS Not An
Error)技术是模板引入的一种特性,替代失败不是错误,这种特性允许了模板中尽管发生不匹配也不会导致编译直接失败,而是由编译器继续去匹配其他类型,这是泛型编程得以实现基础;再者,它允许泛型更灵活地控制和管理各种数据类型行为,为萃取、特化做了铺垫。
任意的模板都体现了SFINAE,例如: 1234567891011121314151617181920212223#include <iostream>using namespace std;struct Test{ typedef int foo;};template<typename T> //#1void func(typename T::foo){ cout<<"void f(T::foo)"<< endl;}template<typename T> //#2void func(T){ cout ...
Modern C++ Design(第二章):Techniques
本文来自Modern C++ Design的第二章:技术,会记录以下技术内容:
Partial template specialization,模板偏特化
Local Classes,局部类
型别与数值间的映射性(Int2type Type2Type class templates)
编译期察觉可转换性和继承性
型别信息及一个容易上手的std::type_info外覆类(wrapper)
Select class template,编译器根据bool状态选择型别;
Traits,traits技术集合
2.1
编译期错误Compile-Time Assertions及定制的错误日志
(注:代码复现价值并不大,因为现在的编译器能直接检出reinterpret_cast的错误转换,报错日志和原书不同;)
考虑一段实现安全转型的代码: 12345678910111213141516#include <iostream>#include <assert.h>using namespace std;template <typename T ...
