
C/C++
dr.xun
迭代
展开
-
API与C++中的API
1、什么是API1、是对某个问题的抽象,及用户与解决该问题的软件组件之间进行交互的方式;2、定义可复用模块,该模块可以嵌入到用户的应用程序中;3、一个明确定义的接口,可以为其他软件提供特定服务。原创 2022-09-11 18:12:28 · 1750 阅读 · 0 评论 -
Linux strcasecmp和strncasecmp函数
strcasecmp和strncasecmp函数的使用说明。原创 2022-08-07 16:01:18 · 832 阅读 · 0 评论 -
安全编码之基于栈的缓冲区溢出
安全编码之基于栈的缓冲区溢出原创 2022-06-04 11:42:44 · 384 阅读 · 2 评论 -
C++编译器解析operator->机制及自锁定技术实现
机制说明编译器可以一个->表达式多次应用operator->,直到找到原始指针。例子好用的RAII手法template<typename T>struct LockingProxy{ LockingProxy(T* pObj) : pointee_ (pObj ) { pointee_->lock(); } ~LockingProxy() { pointee_->unlock(); } T* operator->() c原创 2022-04-19 23:12:04 · 688 阅读 · 0 评论 -
智能指针设计思想
简介smart pointers是一种C++对象,它提供operator->和 unary operator*,藉以模拟一般指针的行为。template<typename T>class SmartPtr{public: explicit SmartPtr(T* pointee) : pointee_(pointee); SmartPtr& operator=(const SmartPtr& other); ~SmartPtr(); T& op原创 2022-04-16 22:40:04 · 738 阅读 · 0 评论 -
C++单例实现实践
简介保证一个class只有一个实体,并为它提供一个全局访问点。种经过改进的全局变量。懒汉模式版本一class Singleton {public : static Singleton* instance() { if (!pInstance_) pInstance = new Singleton(); return pInstance_; }private : Singleton(); Singleton(const Singleton&); ~原创 2022-04-15 22:56:49 · 640 阅读 · 0 评论 -
内存管理——小型对象分配器实践输出
【注】此实践的基本思路来自《Modern C++ Design》四层结构实现Chunkstruct Chunk{ Chunk() : pData(nullptr), firstAvailableBlock_(0), blocksAvailable_(0) { } Chunk(size_t blockSize, unsigned char blocks) { pData = new unsigned char[blockSize * blocks]; firstAvailab原创 2022-04-12 22:55:56 · 1416 阅读 · 0 评论 -
C/C++通用内存分配器原理解析
C/C++分配器存在的问题1、分配速度慢,通常用于为大型对象(数百个或数千个bytes)分配内存2、存在一个管理内存的记忆池,常会耗用一部分内存资源,对于new分得得每一块内存,都会对其进行登记,而登记所需内存达4~32个bytes,对于分配小型对象,用于登记所需内存占比大,不适合用于分配小型对象的内存。内存分配器的工作方式内存分配器管理一个由raw bytes所组成的内存池,能够从池中分配任意大小的内存区块。管理内存需要的簿记结构,内存控制块:struct MemControlBlock {原创 2022-04-09 22:02:21 · 1468 阅读 · 0 评论 -
利用模板别名using实现TypeList
实现TypeListtemplate<typename T, typename U>struct TypeList{ using Head = T; using Tail = U;};背后的机制template参数可以是任何型别,包含该template的其他具现体。作用TypeList 内部没有任何数值:它们的实体是空的,不含任何状态,也未定义任何函数。执行期间t不带任何数值。它存在的理由只是为了携带型别信息。使用例子:using CharList = TypeLis原创 2022-03-26 23:38:05 · 712 阅读 · 0 评论 -
模板技术之编译期识别类型转换和继承性
问题如何识别两个模板参数T和U是否有继承关系?原理sizeof的威力sizeof可以用于任何表达式,在编译期评估表达式类型的大小。因此,sizeof可以感知重载、模板实例化、转换规则,或任何可发生于C++表达式身上的机制。识别类型转换能力机制运用sizeof和重载函数。1、函数重载提供选择分支提供两个重载函数:一个接受目标类型U——1号函数,另一个接受其它任何类型——2号函数。用户用类型T来调用这些函数,用户想知道T是否可以转换成U。如果1号函数被调用,说明T可以转换成U,否则无法转换成U。原创 2022-03-23 23:05:59 · 1191 阅读 · 0 评论 -
模板技术之型别转换实现Tag
型别映射问题:C++中不存在函数模板偏特化有时我们期待型别转换,输入一种数据类型,输出另一种数据类型,如下代码所示。template<typename T, typename U>T* Create(const U& arg){ return new T(arg);}有时,系统中存在旧代码,如Widget,需要两个参数才能构建出对象,第二个参数固定为-1,它的派生类则没有这种问题。由于函数模板特性限制,我们如下代码不符合规则。//非法代码template<t原创 2022-03-22 23:43:19 · 1144 阅读 · 0 评论 -
template技术之数字型别化实现编译期分派工作
数字型别化template<int v>struct Int2Type{ enum { value = v };};作用: 根据引数所得的不同数值来产生不同型别。eg: Int2Type<1>与Int2Type<2>是不同的数据类型,通过它可以在编译期选择不同数据类型,即编译期的条件判断。使用场景需满足以下两个条件:1、有必要根据某个编译期常数调用一个或数个不同的函数。2、有必要在编译期实施“分派”( dispatch) 。例子选择函数temp原创 2022-03-20 00:03:21 · 117 阅读 · 0 评论 -
C++局部类的一种使用场景
局部类局部类的限制local class不能定义static成员变量,也不能访问non-static局部变量。使用场景例子:适配器class Interface{public: virtual void fun () = 0;};template <class T, class P>Interface* MakeAdapter(const T& obj, const P& arg ){ class Local : public Interface {原创 2022-03-19 23:39:24 · 560 阅读 · 0 评论 -
技术之编译器检查
编译器检查特点:静态类型检查可定制类型错误消息例子:实现安全转型的函数,并确保较大型别不能转换成较小型别。迭代一template <typename To, typename From>To safe_reinterpret_cast(From sfrom){ assert(sizeof(From) < sizeof(To)); return reinterpret_cast<To>(from) ;}上述代码,会在执行期进行断言。迭代二 期待编译原创 2022-03-18 23:41:17 · 794 阅读 · 0 评论 -
template应用之Policies和Policy Classes
Policies和Policy Classes什么是Policy?Policy定义一个class或class template的接口,该接口由内隐型别定义( inner type definition) 、成员函数和成员变量之一或全部组成。例子声明Policy:policy_Create()可以理解为一种语法约束:要有Create()接口Create()返回值必须是T*template<typename Policy>struct Creator{ explicit Cr原创 2022-03-14 23:06:38 · 894 阅读 · 0 评论 -
多重继承与template结合增强设计
多重继承优点有助于产生更富弹性的设计,扩展性好具备封装性缺点缺乏技术(Mechanics ),仅仅只是将被组合的base classes结合在一起并建立一组用来访问其成员的简单规则缺乏型别信息(Type infornation),Based classes并没有足够的型别信息来继续完成它们的工作缺乏弹性的数据处理,base classes实作之各种行为必须操作相同的数据。这意味着他们必须虚继承一个持有该数据的base class。由于总是由user classes继承librar原创 2022-03-13 12:42:25 · 396 阅读 · 0 评论 -
试用std::once_flag和std::call_once保护数据只一次初始化
1、once_flag源码struct once_flag { private: typedef __gthread_once_t __native_type; __native_type _M_once = __GTHREAD_ONCE_INIT; public: /// Constructor constexpr once_flag() noexcept = default; /// Deleted copy constructor o原创 2022-01-10 22:59:12 · 713 阅读 · 0 评论 -
实现线程安全栈Stack
实现线程安全栈Stack封装stack,削减接口采用栈管理内存分配Stack实现#pragma once#include <exception>#include <memory>#include <stack>#include <mutex>struct EmptyStack : std::exception{ const char* what() const noexcept { return "t原创 2022-01-09 13:47:48 · 3327 阅读 · 0 评论 -
线程间共享数据笔记
原创 2021-10-06 14:26:19 · 105 阅读 · 0 评论 -
std::thread使用注意资源回收问题
一、线程1、启动线程存在的固有开销1. OS分配内核资源、堆栈空间2. 将线程加入调度器2、每个线程都需要一份独立的堆栈空间对于32位系统,一个线程占用1MB的栈空间3、线程间的任务调度,OS需要做上下文切换因此,1. 线程启动后,需要关注其销毁2. 系统资源有些,需要考虑启动线程的数量是否合适二、thread使用问题1、启动线程,主线程抛异常,异常退出例子:#include <iostream>#include <thread>using namesp原创 2021-10-04 11:35:19 · 2375 阅读 · 0 评论 -
LeetCode 28. 实现 strStr()
一、题目实现 strStr() 函数。给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。说明:当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。示例 1:输入:haystack = “原创 2021-06-27 20:38:25 · 125 阅读 · 1 评论 -
LeetCode 27. 移除元素
一、题目给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。说明:为什么返回数值是整数,但输出的答案是数组呢?请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。你可以想象内部操作如下:// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝原创 2021-06-23 21:06:04 · 140 阅读 · 0 评论 -
C++智能指针
原创 2021-06-20 16:14:24 · 133 阅读 · 0 评论 -
C++类型推导
原创 2021-06-20 16:11:50 · 194 阅读 · 0 评论 -
智能指针实现Impl模式
widget.h:class Widget{ public: Widget(); ~Widget(); // ... other funcs Widget(const Widget& rhs); / Widget& operator=(const Widget& rhs); private: struct Impl; std::unique_ptr<Impl> pImpl;};widget.cpp:struct Widget::Impl原创 2021-06-20 15:56:29 · 251 阅读 · 0 评论 -
实现make_unique
template<typename T, typename... Ts>std::unique_ptr<T> make_unique(Ts&&... params){ return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));}原创 2021-06-20 15:38:11 · 354 阅读 · 0 评论 -
一次正交设计和组合设计之旅
一次正交设计和组合设计之旅引言Design is there to enable you to keep changing the software easily in the long term. – Kent BeckEverything should be made as simple as possible, but not simpler. – Albert Einstein一、回顾设计的定义及价值定义:如引言中Kent Beck言,软件设计是为了长期更加容易地适应未来的变化。价值:原创 2021-06-19 18:55:35 · 773 阅读 · 1 评论 -
LeetCode10:正则表达式匹配
给你一个字符串s和一个字符规律p,请你来实现一个支持 '.'和'*'的正则表达式匹配。'.' 匹配任意单个字符'*' 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。示例 1:输入:s = "aa" p = "a"输出:false解释:"a" 无法匹配 "aa" 整个字符串。示例 2:输入:s = "aa" p = "a*"输出:true解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 '...原创 2021-05-15 21:22:34 · 113 阅读 · 0 评论 -
C++零初始化(Zero Initialization)
下面的语句定义了一个初始值为0的整型变量:int counter {0}; // counter starts at zero我们可以忽略这里带括号的初始化式中的0,效果是一样的。定义counter的语句可以这样写:int counter {}; // counter starts at zero说明:空花括号有点像数字0,这使得这个语法很容易记住。零初始化适用于任何基本类型。例如,对于所有基本的数字类型,总是假定带括号的空初始化式包含数字零。摘自:beginning-c20-.原创 2021-05-15 19:08:25 · 1296 阅读 · 0 评论 -
C++11 外部模板
【转载至】C++11 外部模板 - kaizen - 博客园 (cnblogs.com)【1】引入外部模板为了解决什么问题?“外部模板”是C++11中一个关于模板性能上的改进。实际上,“外部”(extern)这个概念早在C的时候已经就有了。常见的情况,在一个文件a.c中定义了一个变量int i,而在另外一个文件b.c中想使用它,这个时候就会在没有定义变量i的b.c文件中做一个外部变量的声明。比如:// 声明在b.c文件中extern int i;这样做的好处是,在分别编译了a.c和b转载 2021-05-14 09:25:00 · 543 阅读 · 0 评论 -
C++编译时类型检查的方法
零、实现自己的swap函数template <class T> void swap ( T& a, T& b );一、类型萃取#include <string>#include <iostream>#include <type_traits>using namespace std;template<typename T>void my_swap(T& a, T& b){ sta原创 2021-04-23 21:15:58 · 1011 阅读 · 0 评论 -
C++内存管理
1、基本要求“不重不漏”:不重——不重复delete,不漏——不漏掉delete即,new/delete要配对2、配对的场景malloc()分配内存,用free()释放内存 用new表达式创建对象,需用delete表达式析构对象并释放内存 用new[]表达式创建对象,需用delete[]表达式析构对象并释放内存 用::operator new()分配内存,需用::operator delete()去释放 用placement new创建对象,需在对象的生命期结束时调用对象的析构函数原创 2021-04-17 21:58:47 · 96 阅读 · 0 评论 -
泛型编程之泛型参数
一、泛型参数问题:用C++语言实现求一个数的平方。分析:一个数,可以是int、double、complex等,规则求数的平方"x*x"伪代码:sqrt(x) return x * x;实现一:提供一组用于求不同数字类型的平方函数。int sqrtInt(int x){ return x*x;}int sqrtDouble(double x){ return x*x;}// ...实现二:上述一组函数,对不同的数字类型,有...原创 2021-03-21 10:19:12 · 1515 阅读 · 0 评论 -
C++技术之多态实现非成员函数行为的虚化
一、原理利用C++多态技术实现非成员函数行为的虚化是指多态类中写一个虚函数做实际工作,并增加一个函数只负责调用多态类的虚函数,根据入参所指的实际对象的不同调用不同的虚函数实现。二、样例#include <ostream>#include <iostream>using namespace std;struct NLComponent{ virtual ostream& print(ostream& s) const = 0;原创 2021-03-20 22:47:49 · 160 阅读 · 0 评论 -
C++技术之虚化拷贝构造函数
一、虚函数返回类型的语法规则当子类(derived class)实现父类(base class)的一个虚函数时,不在一定得声明与原本形同的返回类型。如果函数的返回类型是一个指针或者引用,指向父类(base class),则子类(derived class)的函数可以返回一个指针或者引用指向该父类(base class)的一个子类(derived class)。二、样例#include <list>struct NLComponent{ virtual NLCompo原创 2021-03-20 22:33:10 · 850 阅读 · 0 评论 -
设计模式之线程安全单例Singleton
方式一:利用Linux线程库pthread_once实现。noncopyable.h#pragma oncestruct noncopyable{protected: noncopyable() = default; ~noncopyable() = default; private: noncopyable(const noncopyable&) = delete; noncopyable& operator=(const non原创 2021-03-14 16:46:56 · 156 阅读 · 0 评论 -
std::bind 和 std::placeholder占位符
1、std::bind用来绑定函数调用的参数,用于解决我们有时候可能并不一定能够一次性获得调用某个函数的全部参数,通过这个函数,我们可以将部分调用参数提前绑定到函数身上成为一个新的对象,然后在参数齐全后,完成调用的场景。2、std::placeholders定义:namespace placeholders { extern /* unspecified */ _1; extern /* unspecified */ _2; extern /* unspecified */原创 2021-03-13 21:20:22 · 1856 阅读 · 0 评论 -
现代C++变长参数模板
一、变长参数模板定义自C++11后,C++开始支持变长参数模板,允许任意个数、任意类别的模板参数,不需要在定义时将参数的个数固定。其形式定义如下:template<typename... Ts> class Variadic;其模板实例化:1. 0个参数的模板类 Variadic<> zero;2. 多个参数的模板类 Variadic<int, double, std::string, std::list<int>> sample;.原创 2021-03-13 20:59:01 · 779 阅读 · 0 评论 -
模仿std::function实现监听者模式
template< class > class function; /* undefined */ template< class R, class... Args > class function<R(Args...)> #include <functional>#include <vector>#include <iostream>template<typename...原创 2021-03-11 22:19:54 · 156 阅读 · 0 评论 -
Linux进程间同步之wait
一、关于系统级函数wait1、作用 实现进程同步。 当子进程执行时, wait()可以暂停父进程的执行,使其等待。一旦子进程执行完,等待的父进程就会重新执行。如果有多个子进程在执行,那么父进程中的 wait()在第一个子进程结束时返回,恢复父进程执行。2、函数信息头文件:sys/wait.h函数签名:pid_t wait(int *status)说明: 形参:如果status是一个指向整型数的指针,当wait 返回时,该指针就指向子进程退出时的状态信息...原创 2021-02-06 19:44:24 · 1742 阅读 · 0 评论