C++
文章平均质量分 79
Chris_zhangrx
读书郎
展开
-
[CMake] CMake 基础命令
本文主要是对 https://github.com/ttroy50/cmake-examples 项目进行学习,并记录。本章主要包含了一些常用的 CMake 基本命令,以及存在子项目时的相关内容。首先需要注意的一点是,开头需要指定使用的 Cmake 版本,以及给 Project 一个名字:然后可以根据需求设置相关的编译语言版本:这里就引入 cmake 中 变量(variable)的概念。 其基本都是全大写的名字,防止与用户输入的其他命令混淆。只是这里有一部分 cmake 自己预留的变量名了。例如:C原创 2022-12-03 17:56:18 · 994 阅读 · 0 评论 -
如何写出好的变量名
本文内容主要是摘抄自《代码大全》中与变量名相关章节的内容,阐述当需要一个好的变量名需要注意哪些点。原创 2022-10-24 07:46:08 · 450 阅读 · 0 评论 -
内存模型与C++ 内存序
介绍cpu 内存模型与 C++ 6 种内存序原创 2022-09-19 09:35:54 · 6052 阅读 · 6 评论 -
JIT 和 AOT
JIT 和 AOT本文内容主要来自于偶然看到的一个 b 站视频:https://www.bilibili.com/video/BV1134y1h7ED?spm_id_from=333.999.0.0之前就不断的在各种不同的场合看到 JIT 编译,AOT 编译,除了基本概念一直对这二者都是比较模糊的概念。通过视频中的介绍有了更多的理解,简而言之:JIT 是动态编译,会有更多地运行时信息,可以做更激进的编译优化,更耗内存AOT 是静态编译,更多偏控制型指令的优化,为了保证正确性,编译优化相对比较保守。原创 2022-05-23 22:12:55 · 867 阅读 · 2 评论 -
[读书笔记]《深度探索C++对象模型》
文章目录前言第一章 关于对象第二章 构造函数语意学构造函数拷贝构造函数初始化列表第三章 Data 语意学第四章 Function 语意学非静态成员函数静态成员函数虚成员函数第五章 构造、析构、拷贝语意学RTTI模板函数的实现逻辑前言俗话说得好,好记性不如烂笔头,本文主要是重温了一下经典书籍《深度探索C++对象模型》,然后一些内容摘录,主要记录的是我自己的精简版,建议读者有相关的知识需要还是慢慢去啃一下原书比较好。第一章 关于对象首先介绍了 C++ 类的情况, C++类的内存存储方式是:只包含非静态成原创 2022-01-09 17:02:29 · 1229 阅读 · 0 评论 -
Caffe 源码(二) —— common 文件
caffe 源码 —— common.hpp/cpp这里主要是对 caffe 框架源码进行梳理与学习(主要是 CPU 模式下的,所以暂时还不涉及 CUDA,cudnn 编程),不同时期回看源码收获不同,水平有限,如有错误之处还请留言指正交流。首先的切入点就是 common.hpp, 其包含在 blob.hpp 和 layer.cpp 头文件中,而 blob.hpp 和 layer.cpp 这两...原创 2019-11-14 19:56:08 · 459 阅读 · 0 评论 -
[设计模式] —— Composite 组合模式
文章目录Composite 组合模式动机定义示例代码结构图总结Composite 组合模式属于数据结构模式,常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大破坏组件的复用,这时,将这些特定的数据结构封装在内部,对外提供统一接口来实现与特定数据结构无关的访问。动机客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来代码的维护性、扩展性等弊端。如何将”客户代码与复杂的对象容器结构“解耦?让对象容器自己原创 2021-12-21 10:10:39 · 563 阅读 · 0 评论 -
[设计模式] —— Adapter 适配器模式
文章目录Adapter 适配器模式动机定义示例代码结构图总结Adapter 适配器模式属于接口隔离模式,在组件构建过程中,某些接口之间直接的依赖经常会带来很多的问题,甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来就互相紧密关联的接口是一种常见的解决方式。动机在软件系统中,由于应用环境变换,常需要将”一些现在的对象“ 放在新的环境中应用,但是新环境要求的接口是这些现有对象所不满足的。如何应对这种”迁移式变化“?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所需求的接口?定义原创 2021-12-21 09:36:11 · 280 阅读 · 0 评论 -
[设计模式] —— Flyweight 享元模式
文章目录Flyweight 享元模式动机定义示例代码结构图总结Flyweight 享元模式属于对象性能模式,主要考虑面向对象所带来的成本问题。动机软件系统采用纯对象方案的问题在于大量细粒度的对象会很快充斥整个系统,从而带来很高的运行时代价。如何避免大量细粒度对象问题的同时,让外部客户程序依然能够透明地使用面向对象的方式来进行操作?定义运行共享技术有效地支持大量细粒度的对象。示例代码class Font {private: string key; // ...public: F原创 2021-12-21 08:49:02 · 315 阅读 · 0 评论 -
[设计模式] —— Singleton 单例模式
Singleton 单例模式属于对象性能模式,主要考虑面向对象所带来的成本问题。动机在软件系统中,有一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例。这应该是设计者的责任,而不是使用者的责任。定义保证一个类仅有一个实例,并提供一个该实例的全局访问点。示例代码class Singleton {private: Singleton(); Singleton(const Singleton&a原创 2021-12-21 08:32:27 · 470 阅读 · 0 评论 -
[设计模式] —— Builder 生成器模式
文章目录Builder 生成器模式动机定义示例代码结构图总结Builder 生成器模式动机面临着”一个复杂对象“的创建工作,其通常由各个部分的子对象用一定的算法构成,由于需求变化,这个复杂对象的各个部分经常变化,但它们组合在一起的算法很稳定。定义将一个复杂对象与其表示分离,使得同样的构建过程(稳定)可以构建不同的表示(变化)。示例代码class House {public: // ... House* init() { this->BuildPart1(); for原创 2021-12-21 08:14:25 · 507 阅读 · 0 评论 -
[设计模式] —— Prototype 原型模式
文章目录Prototype 原型模式动机定义实例代码结构图总结Prototype 原型模式通过对象创建模式,绕开 new,来避免对象创建(new)过程中导致的紧耦合(new 需要依赖具体类),从而支持对象创建的稳定,它是抽象接口后的第一步工作动机某些结构复杂的对象的创建,由于需求变化,这些对象经常面临着剧烈变化,但它们之间却拥有比较稳定一致的接口。如何应对这种变化?如何向”客户程序“(使用这些对象的程序)隔离出这些易变得对象,从而使依赖这些依赖这些易变对象的客户程序不随需求改变而改变。定义使用原创 2021-12-20 23:41:12 · 312 阅读 · 0 评论 -
[设计模式] —— Abstract Factory 抽象工厂模式
文章目录抽象工厂动机定义示例代码结构图总结抽象工厂通过对象创建模式,绕开 new,来避免对象创建(new)过程中导致的紧耦合(new 需要依赖具体类),从而支持对象创建的稳定,它是抽象接口后的第一步工作动机主要是解决一系列”相互依赖的对象“,工厂方法是解决”单个对象“,即多个 Factory 组成一个总的基类。定义提供一个接口,让该接口创建一系列”相关或者相互依赖的对象“,无需指定它们的具体类。示例代码class EmployeeDAO {public: vector<Employ原创 2021-12-19 12:33:15 · 923 阅读 · 0 评论 -
[设计模式] —— Factory Method 工厂模式
文章目录工厂模式动机定义示例代码结构图总结工厂模式通过对象创建模式,绕开 new,来避免对象创建(new)过程中导致的紧耦合(new 需要依赖具体类),从而支持对象创建的稳定,它是抽象接口后的第一步工作动机在软件系统中,经常要有创建对象的工作,由于需求变化,需要创建的对象的具体类型经常变化。如何应对这种变化?如何绕开常规的 new,提供一种”封装机制“来避免客户程序和这种”具体对象创建工作“的紧耦合?定义定义一个用于创建对象的接口,让子类决定实例化哪个类。Factory Method 使得一个原创 2021-12-19 12:30:52 · 696 阅读 · 0 评论 -
[设计模式] —— Bridge 桥模式
文章目录桥模式动机定义示例代码结构图总结桥模式软件组件的设计中,如果责任划分的不清晰,使继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码。动机由于某些固定的固有实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。如何应对”多维度的变化“?如何利用面对对象关系技术来使得类型可以轻松沿着两个乃至更多的方向变化而不引入额外的复杂度。定义将抽象部分(业务功能)与实现部分(平台实现)分离,是它们都可以独立变化。示例代码class Messager {public: //原创 2021-12-19 01:33:04 · 396 阅读 · 0 评论 -
[设计模式] —— Decorator 装饰模式
文章目录装饰者模式动机定义示例代码结构图总结装饰者模式装饰模式属于单一职责模式分类里的。软件组件的设计中,如果责任划分的不清晰,使继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码。动机过度地使用继承来扩展兑现的功能,由于继承为类型引入的静态特质(定死一定只会调用子类),使扩展的当时缺乏灵活性,并且随着子类的增多(功能扩展的增多),各种子类的组合(对扩展功能的组合)会导致更多子类的膨胀。如何动态实现“对象功能的扩展”,同时避免组合过多呢?定义动态(组合)地给一个对象增加一些额原创 2021-12-18 23:37:37 · 762 阅读 · 0 评论 -
[设计模式] —— Observer 观察者模式
动机我们需要为一些对象建立一种“通知依赖”关系,即一个对象状态发生变化,所有的依赖对象(观察者对象)都将得到通知,如果依赖过于紧密,软件不能很好地抵御变化。面向对象技术可以使这种依赖关系弱化,并形成一种稳定的依赖关系,从而体系结构会松耦合。定义对象间一种一对多(变化)的依赖关系,以便当一个对象的状态(目标对象)发生变化时,所有依赖它的对象都得到通知并自动更新。示例代码class FilterSplitter {private: string m_filePath; int m_fileNum原创 2021-12-17 10:58:44 · 648 阅读 · 0 评论 -
[设计模式] —— Strategy 策略模式
文章目录动机定义示例代码结构图总结动机某些对象使用的算法可能多种多样,经常改变,将这些算法都编码到对象中,使对象变得异常复杂,而且有时支持不适用的算法也是一种性能负担。想要在运行时根据需要透明地更改对象的算法,就要将算法与对象本身解耦,从而避免上述问题。定义定义一系列算法,把它们一个个封装起来,并且它们可以相互替换(变化),该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。示例代码enum TaxBase { CN_Tax, USA_Tax};class原创 2021-12-17 09:37:57 · 756 阅读 · 0 评论 -
[设计模式] ——Template Method 模板模式
组件协作模式通过晚绑定,来实现框架与应用程序之间的松耦合。是框架和引用程序协作常用的。Template Method 模板模式动机有完整的,稳定的整体操作,但子步骤却有很多变化的需求,或者无法和整体结构同时实现(有早晚关系)定义定义一个操作中的算法骨架(稳定点),而将一些步骤延迟(变化点)到子类中,Template method 使子类可以不改变一个算法的结构即可重定义(override 重写)该算法的某些步骤。示例代码这里给出的 demo 的图示如上,假设这里算法的实现主题有 5 个接口,原创 2021-12-17 00:20:21 · 456 阅读 · 0 评论 -
[设计模式] —— 设计模式的介绍及分类
前言深入理解面向对象向下:深入理解三大面向对象机制:封装:隐藏内部实现继承:复用现有代码多态:改写对象行为向上:深刻把握面向对象机制所带来的抽象意义,理解如何使用这些机制来表达现实世界,掌握什么是"好的面向对象设计"。一般设计模式都是用来解决复杂性问题的,而人们解决复杂性问题主要有两个角度:分解:即分而治之,将大问题分解成多个小问题,将复杂问题分解为多个简单问题。抽象:不能掌握所有复杂的对象,我们就选择忽视它的非本质细节,而去处理泛化和理想化了的对象模型。在前面的博客中也介绍了一原创 2021-12-16 22:07:12 · 632 阅读 · 0 评论 -
编译 llvm Kaleidoscope example 错误
这里是记录在编译 llvm 官方 tutorial 时,前两章都是使用的标准库,在第 3 章就开始依赖 llvm 项目工程的内容了。官网编译命令为:clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core` -o toy在本地编写代码,编译时可能会遇到以下问题:头文件找不到fatal error: ‘llvm/ADT/APFloat.h’ file not found#include原创 2021-11-16 09:02:34 · 1781 阅读 · 4 评论 -
error: invalid application of ‘sizeof‘ to incomplete type “xxxxx“
解决方式报错相关类,或者使用相关类作为类成员函数的类析构函数需要使用 default 关键字。问题说明在编译代码时,遇到了 error: invalid application of ‘sizeof’ to incomplete type “mlir::Pass” 的问题,因为相关代码与 std::unique_ptr 相关,遇到这一问题主要是 mlir::Pass 报错的这个类:std::unique_ptr<mlir::Pass> xxxxx;官方关于 std::unique_p原创 2021-11-04 17:22:32 · 5487 阅读 · 0 评论 -
C++ tips
本文暂时收录一下 C++ 一些小的知识点。使用 sstream 等写入数据到文本,换行使用 “\n” 比使用 “std::endl” 快大概 3-5 倍。主要是 “std::endl” 会刷新输出缓存区,下面是实际数据对比:# 使用 std::endl # 使用 \n花费了20.0809秒 花费了4.73334秒花费了4.65392秒 花费了1.16888秒花费了1.37358秒 花费了0.288983秒花费了0.349523秒 花费了0.07281秒原创 2021-08-30 10:56:45 · 180 阅读 · 0 评论 -
[Pytorch 源码阅读] ——torch.trace.jit 接口 C++ 源码阅读
文章目录前言torch::jit::TypeClassTypec10::ivalue::Objecttorch::jit::Objecttorch::jit::Module转化过程总结前言本文主要是从 torch.jit.trace 接口,打开 Pytorch JIT 的大门,介绍在正常 nn.module 经过 Trace 之后形成 scriptModule 的过程和涉及到的 C++ 类,因为涉及到的内容蛮多的,所以这里就从源码的角度介绍了一些相对比较重要,或者是可以帮助我们理解的类。在开始学习之前原创 2021-08-23 08:26:21 · 3545 阅读 · 0 评论 -
[Pytorch 源码阅读] —— 谈谈 dispatcher(二)
文章目录前言源码阅读IValue 类schemaOperatorHandleKernelFunctionOperatorEntryDispatcher内部调用逻辑kernel 是如何注册上的根据数据类型再次分发总结前言这里接上文 [Pytorch 源码阅读] —— 谈谈 dispatcher 中对 Pytorch 中 dispatcher 的相关概念介绍,主要是对相关概念和类间的关系做一个概述,没有读过前面文章的同学建议先读一下前面的文章。这里就是深入各个类的源码,对这些类做一个详细的解读。文章篇幅会原创 2021-08-08 11:40:35 · 2780 阅读 · 1 评论 -
[Pytorch 源码阅读] —— 谈谈 dispatcher(一)
文章目录概念介绍diapatch key 的表示和计算dispatch table 注册boxing 和 unboxing源码分析这篇文章的内容主要还是基于 EdWard z. yang 的 Let’s talk about the PyTorch dispatcher 来梳理一下 Pytorch dispatcher 相关的内容学习以及源码阅读。概念介绍dispatcher 可以理解为分发器,可以根据关于 tensor 输入的一些信息来决定要调用哪一块的程序。其主要是通过分发表(dispatch原创 2021-08-07 19:06:06 · 2611 阅读 · 0 评论 -
[Pytorch 源码阅读] ——Pytorch python 接口的 C 扩展
前言在前面的博客中介绍了 Tensor 相关类的 C++ 实现,本文主要介绍 Pytorch 的 Tensor 是如何在 Python 中使用起来的,更大一点的题目就是 Pytorch 中 python 的 C 扩展,说明 Pytorch 是如何通过 python 接口来调用相关 C++ 实现的。Python c 扩展在开展正式介绍之前,需要先了解一些前提知识,就是标准的 Python c 扩展的一些内容。python 中模块(module)和包(package)的简介:模块(module)就是原创 2021-07-26 10:19:26 · 1700 阅读 · 1 评论 -
[Pytorch 源码阅读] —— Tensor C++相关实现
文章目录版本介绍概念介绍源码分析intrusive_ptr 类TensorImpl 类StorageImpl 类总结版本介绍因为 Pytorch 版本迭代还是蛮快的,这里给出我源码阅读的版本及 commit 号以供参考。master 分支,commit 号: 047925dac1c07a0ad2c86c281fac5610b084d1bd概念介绍Tensor 是 Pytorch 核心的数据结构,使用过 pytorch 的同学想必都不会陌生,它可以包含 scalar type 的数据(例如 floa原创 2021-07-25 21:44:08 · 4021 阅读 · 3 评论 -
libtorch aten::Tensor 与 std::vector 互换
在使用 libtorch 的过程中我们可能会遇到需要 libtorch 中的 at::Tensor 类型转化成 std::vector 常规类型存储,或者从 std::vector 生成一个 at::Tensor 供我们使用。at::Tensor 转 std::vector这里以 at::Tensor 里面的数据类型都是 float 为例,将 std::vector<T> 的 T 直接设置成对应的基本数据类型即可:aten::Tensor ten; // 假设 ten 里面已经有数据了s原创 2021-07-23 21:13:59 · 5568 阅读 · 0 评论 -
[Pytorch 源码阅读] —— TH中的 c 语言泛型编程
前言基于 pytorch 1.10.0 版本,mastercommit 号:047925dac1c07a0ad2c86c281fac5610b084d1bd万事开头难,还是咬着牙开始了 Pytorch 的源码阅读内容,虽然感觉难度很大,而且有点无从下手,希望坚持下去能有所进步!这里光源码编译就花了一些时间,尝试了 macbook,windows,和 linux 下 git clone 源码然后按照官方说明操作,但是基本碍于系统或者网络问题,git 拉第三方以来的时候会有很多问题,最后只是在 li原创 2021-06-20 22:12:01 · 691 阅读 · 1 评论 -
C++11 测试代码运行时间
需要包含 chrono 头文件。#include <chrono>// 设置开始时间auto start = std::chrono::system_clock::now(); // 需要测试代码func();// 设置结束时间auto end = std::chrono::system_clock::now(); // 精确到微秒,除此之外,还有五种时间单位:hours, minutes, seconds, milliseconds, nanosecondsauto原创 2021-06-01 11:44:49 · 508 阅读 · 0 评论 -
C++ 测试驱动开发 TDD(二)
增加Soundex 算法测例 3重构以后可以继续下一个测试,我们可以处理规则2(第一个字母后,用数字替换辅音),替换规则中字母 b 对应数字 1,则可以写下面这样的测例:TEST_F(SoundexEncoding, PadWithZerosToEnsureThreeDigits) { ASSERT_THAT(soundex.encode("Ab"), Eq("A100")); }...原创 2021-05-29 16:50:02 · 962 阅读 · 2 评论 -
C++ 测试驱动开发 TDD(一)
文章目录TDD 介绍Soundex 算法示例介绍增加Soundex 算法测例1增加Soundex 算法测例2Soundex 算法测例1 、2重构增加Soundex 算法测例 3最近阅读了《C++程序设计实践与技巧:测试驱动开发》,也算是第一次系统的了解到 TDD 的概念吧,因为整个调试的过程太细了,想要一次性说明白着实需要一点功力,这里权当一些读后感分享,有兴趣的读者可以自己找到这本书来读读看。 虽然不能说可以立马有所了解,或者就可以在实际业务代码中就用上了,但是总得先有这么一个了解过程嘛。TDD 介绍原创 2021-05-29 16:20:39 · 1464 阅读 · 2 评论 -
STL 系列 —— 迭代器与 traits 编程(二)
文章目录前言迭代器内置类型声明迭代器种类 iterator_category数值型别 value type差距类型 difference typereference type 和 pointer type迭代器type traits前言计算机科学的许多问题,都是通过增加间接层的方式解决的,STL 最为人称道的是将容器和算法的实现分割开了,迭代器就是分开它们必须的中间层。算法是容器的使用者,如若二者不独立开来,算法实现的过程中会暴露很多关于容器使用的细节,而这些细节并不是每个人都可以了解的,何不让相关容器原创 2021-04-18 19:04:50 · 462 阅读 · 0 评论 -
STL 系列 —— 空间配置器(一)
前言《STL 源码剖析》,《泛型编程与STL》这两本书都是候捷大佬译的,且在 《STL 源码剖析》最后推荐读物中也出现了 《泛型编程与STL》的身影,机缘巧合就找了一下相关资源,快速翻看了一下,发现两本书的内容是如此相辅相承的,所以这里就放在一起说一说。虽然天下大作,必作于细,不过目前博主的水平有限,还是在浅浅的一层学习中,所以接下来的系列文章不会深入细节中,否则系列文章难免会变成单纯的读书摘要,又臭又长,也会给阅读的人带来不小的负担。如果对相关细节感兴趣的小伙伴还是可以自行阅读原书籍的。这也是第二遍原创 2021-04-18 13:25:27 · 306 阅读 · 0 评论 -
C++ 处理文本输入
正常C++用流将输入读入以后,用 >> 符号就可以读入,例如输入格式是:123 ABCDEF或者是:123ABCDEF顺序用 fin >> s 即可,其中 s 是 string 类型。当我们获取一个 string 里面的单个字母时,可以借助下面方法: ifstream fin("beads.in"); int n; string s; char c; fin >> n; while (getline(fin, s)) { ist原创 2021-02-28 22:19:13 · 321 阅读 · 0 评论 -
C++ 万能引用与函数重载
在前面两篇博客:C++ 中的左值与右值C++ 中的 std::move 与 std::forward对C++ 中的万能引用及std::forward有了一定的了解,这里主要是要说明当函数使用万能引用时就要小心再使用函数重载了,不然稍不留神就会出现我们意想不到的错误。范例1: 普通函数std::multiset<std::string> names;template<typename T>void logAndAdd(T&& name) { names原创 2021-01-06 22:26:16 · 343 阅读 · 0 评论 -
C++ 中的 std::move 与 std::forward
文章目录std::movestd::forward首先要理解 std::move 和 std::forward 需要对 C++ 中的左值和右值有一个了解,可以参考:C++ 中的左值与右值一般在 C++ 中的移动语义对应的是 std::move ,完美转发对应的是 std::forward。 但是不论是所谓的移动,还是转发,其实代码并没有移动或者转发任何东西,它们唯一做的就是强制类型转换。 std::move 做的是无条件的将实参强制转换成右值,而 std::forward 则仅在某个特定的条件下才强制原创 2021-01-04 22:35:51 · 347 阅读 · 0 评论 -
C++ 中的左值与右值
C++ 左值与右值C++ 非常注重运行效率,而 C++11 被最广泛接受的可能就是移动语义,而移动语义的基础在于区别左值表达式和右值表达式,因为一个对象是右值意味着能够对其实施移动语义,左值不可以。这里对左值右值的理解不能再以变量在表达式的左边还是右边来判定了。判断一个表达式是左值还是右值概括来说:左值表达式是可以对其取地址的 (形参总是左值)右值表达式不可以(临时对象)如果只是看明白了上面两句话就觉得已经具备足够的能力来分辨了,那可能还是有点难度的。int a; // a 可以对其取地址,原创 2021-01-04 21:27:53 · 289 阅读 · 0 评论 -
C++模板
模板定义首先模板是 C++ 泛型编程的基础。主要形式是:template <typename T> xxx模板的主要作用是可以让代码最大限度复用。根据模板参数 T 的位置,模板参数可以分为类型模板参数( T 表示数据类型,形如:T a,这里表示数据 a 是 T 类型的)以及非类型模板参数(T 表示数据,形如:char(&p)[T],这里表示可变的数组长度)按照模板参数使用场景可以分为为:函数模板 和 类模板。在实际我们指定模板实参绑定到模板行参(T)以后,编译器会根据实际参数原创 2020-12-23 22:06:09 · 171 阅读 · 0 评论