库设计:一个简单的Logger库
库设计:一个简单的Logger库架构想法 我们想要写一个简单的Logger库。最简单的想法实际上就是封装fstream下的ofstream的输出方法。然而,我们的Logger有的时候是希望向控制台输出,有的时候是希望向文件输出,有的时候可能是希望向其他地方输出。那么,我们应该如何设计并且导出呢?
我们这次使用的是作为动态库导出的最常见的方法:也就是Impl方法。简单的讲,他就是使用一个简洁的接口向外提供接口符号,内部的实现可能是复杂而又错乱的。我们来看一个图:
我设计的架构如下:
如你所见,我们只需要只是看到了Logger库的不同的行为但是实际上可能是对应的不同的子类来完成这件事情。
下面就是写代码:
接口
logger.h
#ifndef BASICLOGGER_LOGGER_H
#define BASICLOGGER_LOGGER_H
class LoggerImpl;
#ifndef CCSTD_Export
#define CCSTD_Export __declspec(dllexp ...
EffectiveModernCpp
Effective Modern C++理解模板类别推导 一个良好风格程序,是可以让客户程序员对其原理一无所知但是却用的相当的satisfied的!
符合上述陈述的,就是模板类别推导机制。这里有一小段伪代码可以view一下:
template<typename T>
void f(ParamType param); // ParamType is a compound of T
一次调用:
f(expr);
在编译期间,我们的编译器通过expr推导两个型别:一个是T,另一个是ParamType,这个ParamType,往往会有一些饰词:举个例子:
template<typename T>
void f(const T& param);
调用如下:
int x = 0;
f(x);
不会违背我们常识的——我们马上拿到了T是int,而ParamType是const T&
结合我们的开发经验,可以知道 ...
Linux漫游合集
Linux漫游导论Linux系统编程之旅Start 首先就要谈谈内核是什么:
一般的讲,也就是我们在这本书提到的那样的东西——是指管理和分配计算机资源(即CPU、RAM 和设备)的核心层软件。值得一提的是——内核让我们的程序运行更加的简单。
内核的职责,有六个:
进程调度:计算机内均配备有一个或多个 CPU(中央处理单元),以执行程序指令。
“多任务”意指多个进程(即运行中的程序)可同时驻留于内存,且每个进程都能获得对 CPU 的使用权。“抢占”则是指一组规则。
内存管理:内核必须以公平、高效地方式在进程间共享这一资源
提供了文件系统:内核在磁盘之上提供有文件系统,允许对文件执行创建、获取、更新以及删除等操作。
创建和终止进程:内核可将新程序载入内存,为其提供运行所需的资源(比如,CPU、内存以及对文件的访问等)。这样一个运行中的程序我们称之为“进程”。一旦进程执行完毕,内核还要确保释放其占用资源,以供后续程序重新使用。
对设备的访问:计算机外接设备(鼠标、键盘、磁盘和磁带驱动器等)可实现计算机与外部世界的通信,这一通信机制包括 ...
OCR开发库日志记录
OCR开发库日志简介 本次我二次封装的是Tesseract这个OCR库。我们首先扯一下啥是OCR,它指直接将包含文本的图像识别为计算机文字(计算机黑白点阵)的技术。图像中的文本一般为印刷体文本。
首先,想要使用这个库就需要下载相关的二进制资源(这里我不想编译了,没有特殊的需求),只需要在Home · UB-Mannheim/tesseract Wiki (github.com)下载库即可。值得注意的是他会有选项让你勾选是否下载文字数据集。我的建议是直接杀去github仓库下而不是勾上这个选项,否则所有的语言的文字数据集,造成不必要的硬盘空间浪费。
下载结束,我们需要配置的是指向数据集地址的系统变量:
TESSDATA_PREFIX
务必指定这个变量,否则当我们在使用command-line测试的时候会爆出错误,也就是无法加载数据集的错误。
下一步就是找到tesseract.exe,他就在我们下载的位置下方,其基本的指令格式是
tesseract pic.png path/to ...
MissingClassInCS
计算机教育中缺失的一课 · the missing semester of your cs education (missing-semester-cn.github.io)
Missing Class in Computer Scienceshell的简单使用 我们现在就可以开始使用shell了,我们可以创建简单的变量
$ foo=bar
$ echo foo
bar
值得注意的是空格在这里就会显得关键,我们如果一不小心多打了空格,就会发现shell爆错误了:
我们可以使用$符号表示对变量名的解析。
$ echo "We can get the value of the foo that foo is $foo"
We can get the value of the foo that foo is bar
当然,我们的重点是去写简单的shell脚本
vim makeDir.sh
makeDir(){
mkdir -p "$1"
cd "$1"
}
...
MITS6081 Notes
MIT 6.S081概述 操作系统有很多不同的种类,其中一个就是对硬件的抽象。要知道硬件给予的接口一般都很原始,我们操作系统就是提供一个更加高级的接口为应用程序服务:比如说方便且具有可移植性的通过进程或者是文件系统等抽象(虚拟/抽象) 另一个重要的功能就是为许多应用程序提供复用硬件的能力(如你可以在一个操作系统中同时运行一个文本编辑器,录音机或者是多个数据库服务器等)值得注意的是,它们的运行之间互相并不干扰,这就是操作系统给上层提供的一种叫做“虚拟”的抽象(多路复用)我们把强调互不干扰这个方面功能,我们叫做隔离性; 另一方面,一些不相同的用户进程中文件的交流可能需要用到一些共享数据,这个就叫做共享能力。 进一步去想的我们的数据不是随时随地都可以被随意的共享,是我们用户需要共享数据时才会去共享,不想共享共享数据时就不去共享,我们称这实现这样功能的系统叫做安全权限或者是系统权限系统,即访问控制系统。接着,操作系统应该能为大多数应用软件至少提供硬件资源分配的能力,甚至还会去试着去提高程序的性能 我们尝试将计算机抽 ...
Cpp异常处理与并发编程简单笔记
C++ 新特性学习异常处理 Exception Handle 我们简单的聊聊异常处理先:
C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。
void handleError(){
try
{
try {
// do sth
// and sth bad occurred
throw "An error occurred!";
/ ...
xv6速通
从xv6速通出发了解操作系统概貌概论 系统调用操作系统工作的主要概论:
将计算机的资源在多个程序间共享,并且给程序提供一系列比硬件本身更有用的服务。
管理并抽象底层硬件,举例来说,一个文字处理软件(比如 word)不用去关心自己使用的是何种硬盘。
多路复用硬件,使得多个程序可以(至少看起来是)同时运行的。
最后,给程序间提供一种受控的交互方式,使得程序之间可以共享数据、共同工作。
这就是操作系统的主要工作
操作系统的工作方式 实际上是完成初始化硬件和软件的工作之后就陷入一个loop,之后上层软件以require的方式向操作系统发出请求提供服务。比如说,当文件想要读写的时候他就需要去前往操作系统处申请服务。提供的服务就是系统调用。
进程通过系统调用使用内核服务。系统调用会进入内核,让内核执行服务然后返回。所以进程总是在用户空间和内核空间之间交替运行。
内核使用了 CPU 的硬件保护机制来保证用户进程只能访问自己的内存空间。内核拥有实现保护机制所需的硬件权限(hardware privileges),而用户程序没有这些权限。每一次陷入 ...
2024寒假整活_C_Cppb高级编译技术
C/C++编译技术概论多任务操作系统基础 我们下面首先给出一写有用的抽象概念,请看下图
如上所示,我们使用字节流的抽象集层来看待IO设备,下一步就是主存,表示的是计算机存储下的资源的交互与存储集合
再下一个我们需要关注的就是CPU指令集,他表示着我们需要如何处理数据,他和虚拟内存集合起来被抽象成了进程——也就是活动的程序的最小操作系统分配资源实体。
联合起来操作系统,就是虚拟机——计算机的抽象,我们可以在这些抽象的概念上开展我们的软件设计的活动
存储器的层次结构和缓存策略 现代计算机存储体系分为层级结构,为了缓和CPU和主存访问速度——我们采取了层级的缓存体系。自上而下的——分为
CPU寄存器
一级缓存,二级缓存,三级缓存
主存(RAM,ROM)
本地磁盘
远端存储设备
现在作为多进程的操作系统,每一个进程都采取了虚拟技术,即——每个进程总是认为自己是独立的占用了计算机资源,并不关心其他进程的存在和对实际物理内存的使用的情况——这些问题被扔给了操作系统处理。
...
CMake使用小记-3
CMake小记3: find_package以opencv为例 我们下面就要开始讲授难一些的内容了:也就是当我们的程序需要外部库才能消除未定义符号从而正确的完成构建之后,我们应该如何使用CMake来帮助构建程序。
本文的测试程序如下:
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
std::string path = "/home/charliechen114514/LocalGitProject/CodesExperiments/C++/Cmake_5/desktop2.png";
// 注意path换成自己图片的路径,需要注意的是不要含中文名,否则解析可能存在问题
int main()
{
Mat pic = imread(path);
...