![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C/C++
文章平均质量分 66
Jeff_
面向Google和StackOverflow编程的小学生。
展开
-
关于typedef的用法总结
typedef的应用typedef是C 语言中用于为现有数据类型指定替代名称的关键字。它主要用于用户定义的数据类型,当数据类型的名称在程序中使用变得稍微复杂时。以下是使用的一般语法typedef <existing_name> <alias_name>应用一:结构体别名typedef也可用于为用户定义的数据类型命名。让我们看看它对结构体的使用。// ======== oldstruct type_name{ type member1; type me原创 2021-08-22 17:30:01 · 1067 阅读 · 0 评论 -
设计模式:创建型模式之工厂模式(c++)
前言工厂方法模式(英语:Factory method pattern) 又称为 虚拟构造函数、Virtual Constructor、Factory Method,是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型,工厂方法让类的实例化推迟到子类中进行。简单工厂模式简单工厂模式我们将其分为以下几类:工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。抽象产品角色:它一般是具体产品继承的父类或者实现的接口。具体产品角色:工厂类所创建的对象就是此角色的原创 2021-04-07 23:59:33 · 226 阅读 · 0 评论 -
我们是否需要 do...while(0)
1. 前言在许多C / C ++宏中,可以看到许多看起来毫无意义的do while循环中的宏代码。Like:#define FOO(X) do { f(X); g(X); } while (0)#define FOO(X) if (1) { f(X); g(X); } else它的意义是什么,又有哪些意想不到的好处?2. 引入2.1 条件语句引起的逻辑错误上面例子若使用上诉规则,而直接表达:#define FOO(X) f(X); g(X)现在,如果 FOO(X) 在 if ...原创 2021-01-30 17:53:21 · 188 阅读 · 0 评论 -
c++ 面试笔记(长期更新)
1.map的底层是怎么实现的?map与hashmap的区别?什么时候应该使用map什么时候应该使用hashmap?map底层是使用红黑树RB-tree(非严格平衡二叉搜索树)实现的。hashmap在STL中称为unordered_map,使用哈希表hash实现的。unordered_map(等价于hash_map)和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是红黑树具有自动排序的功能,因此map内部的所有元素都是有序的。而基于哈希表,数据插入和查找的时原创 2020-09-13 19:11:13 · 193 阅读 · 0 评论 -
Curiously recurring template pattern ( 奇怪的重复模板模式,CRTP)
CRTP是 C++中的一种技术,其中Derived类从类模板Base派生。关键是Base已派生作为模板参数。template<class T>class Base{...};class Derived : public Base<Derived>{...};CRTP是仅在需要时才实例化类模板的方法,使用静态多态方式。静态多态与动态多态非常相似。但是与使用虚拟方法的动态多态性相反,方法调用的调度将在编译时进行。// crtp.cpp#include <翻译 2020-05-16 19:36:52 · 506 阅读 · 0 评论 -
Deduction Guides (since C++17)
History在C++98中,使用类模板时,即使从使用中可以明显看出它们的类型,也总是必须提供模板参数:std::pair<int, std::string> p(1729, "taxicab");随着C ++ 11中auto的引入,情况发生了一些变化。可以使用(预先存在的)辅助函数make_pair创建变量,从而避免重复类型:#include <iostream>#include <type_traits>#include <utility>翻译 2020-05-10 23:45:58 · 697 阅读 · 0 评论 -
Class template argument deduction (CTAD) (since C++17)
history在C++98中,使用类模板时,即使从使用中可以明显看出它们的类型,也总是必须提供模板参数:std::pair<int, std::string> p(1729, "taxicab");随着C ++ 11中auto的引入,情况发生了一些变化。可以使用(预先存在的)辅助函数make_pair创建变量,从而避免重复类型:#include <iostream>#include <type_traits>#include <utility>翻译 2020-05-10 23:25:26 · 1579 阅读 · 0 评论 -
The overload Pattern
最近研究有关C ++ 17的书和博客文章时,偶然发现了这种访问模式std::variant:#include <iostream>#include <string>using namespace std;template<class... Ts> struct overloaded : Ts... { using Ts::operator()...;...翻译 2020-04-30 00:12:16 · 435 阅读 · 0 评论 -
C++17 type-safe 的 union:variant
转载自:https://kheresy.wordpress.com/2017/10/16/cpp17-variant/前言std::variant 是 C++17 中,一個新加入標準函式庫的 template 容器;他的概念基本上是和 union(參考)一樣,是一個可以用來儲存多種型別資料的容器。比如說:std::variant<int, double> v;就代表 v ...转载 2020-04-28 23:12:09 · 665 阅读 · 0 评论 -
Flexible Array - 柔性数组
灵活数组成员是一种特殊的数组类型,其中具有多个命名成员的结构的最后一个元素具有不完整的数组类型;也就是说,数组的大小未在结构中明确指定。这种“struct hack”在实践中得到了广泛使用,并得到了各种编译器的支持。因此,已经使用了各种不同的语法来声明灵活的数组成员。对于符合标准的C实现,请使用C标准保证有效的语法。the C Standard, 6.7.2.1, paragraph 18中定...原创 2020-04-27 22:19:58 · 1078 阅读 · 1 评论 -
pimple idiom
我们知道,当对头文件进行更改时,包括它的所有源都需要重新编译。在大型项目和库中,由于即使对实现进行了很小的更改,每个人都必须等待一段时间才能编译代码,这可能会导致构建时间问题。解决此问题的一种方法是使用PImpl Idiom,它将实现隐藏在hearer中,并包括一个可立即编译的接口文件。The PImpl Idiom (Pointer to IMPLementation) 是一种用于将实现与接...原创 2020-04-23 23:17:58 · 398 阅读 · 0 评论 -
Liskov substitution principle (里氏替換原則)
文章目录背景Tom's Penguin Problem背景可替代性是面向对象程序设计中的一项原则,其指出在计算机程序中,如果S是T的子类型,则类型T的对象可以用类型S的对象替换 (即类型T的对象可以用子类型S的任何对象替换 (i.e.向上转型))而不更改程序的任何期望属性(正确性,任务执行等)。更正式地讲,Liskov替换原理(LSP)是子类型关系的特定定义,称为(强)行为子类型化,最初是由...翻译 2020-04-23 20:03:25 · 579 阅读 · 0 评论 -
Object slicing(对象切片)
关于对象切片Thinking in C++中有这么一段话:If you upcast to an object instead of a pointer or reference, something will happen that may surprise you: the object is “sliced” until all that remains is the subobject...原创 2020-04-21 22:50:54 · 1228 阅读 · 2 评论 -
IOC(Inversion of Control 控制反转)
背景我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑。如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。我们可以看到,在这样的齿轮组中,...转载 2019-11-24 23:14:26 · 770 阅读 · 0 评论 -
Most vexing parse (最烦人的解析)
Most vexing parse 在 Scott Meyers 在 Effective STL(2001)中 首次使用 。它在 C++ language standard 的 8.2节中正式定义。Example with classesAn example is:#include <iostream>class Timer {public: Timer(){};};...翻译 2020-04-21 21:01:22 · 371 阅读 · 0 评论 -
Monads in C++ (函数编程)
C ++中的Monad?帖子的名字真奇怪。但这并不奇怪。使用std :: optional C ++ 17可获得monad。Eric Niebler的范围库和扩展的期货也是monads。对于这两者,我们都可以期望在C ++ 20中实现。Bjarne Stroustrup在2016年C ++会议上的“秘密闪电演讲”中介绍了Concepts Lite的一些概念,这些概念我们很可能会在C ++ 20中...翻译 2020-04-12 23:16:41 · 1172 阅读 · 0 评论 -
monadic optional expressions(使用可选monad进行多重错误处理)
错误处理是编程中一个广泛的主题,尤其是在C ++中。我今天想向您介绍的方面是如何处理多个错误。让我们考虑以下4个功能:int f1(int a);int f2(int b, int c);int f3(int d);int f4(int e);f4( f4( f3( f2( f1(42), f1(55) ) ) ) )应该依次调用这些函数:将f1的结果(两次调用)传递给f2,然后...翻译 2020-04-12 15:29:25 · 247 阅读 · 0 评论 -
Event Handling and Condition Variables
本文中我们将讨论多线程中事件处理的需求以及使用条件变量实现功能。Event Handling有时,线程需要等待事件发生,例如条件变为真或任务由另一个线程完成。例如,假设我们正在构建一个基于网络的应用程序。该应用程序执行以下任务,与服务器进行一些握手从XML文件加载数据。对从XML加载的数据进行处理。正如我们看到的,任务1不依赖于任何其他任务,而任务3依赖于任务2。因此,这意味着任务...翻译 2020-04-05 00:16:49 · 173 阅读 · 0 评论 -
std::mem_fn 成员指针包装器
std::mem_fn类成员函数指针(member function pointer),是C++语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息。基本上要注意的有两点:函数指针赋值要使用 & 。( 与静态成员函数或自由函数不同,非静态成员函数不会隐式转换为成员函数指针(this)。)使用 .*(实例对象)或者 ->*(实例对...原创 2020-04-04 19:22:11 · 1254 阅读 · 0 评论 -
async(c++11)
std::asyncstd :: async允许您编写可能在程序主线程之外的一个或多个单独线程中运行的代码。std :: async可以看作是std :: threads的高级接口。其是一个函数模板,接受回调(即函数或函数对象)作为参数,并有可能异步执行它们。template <class Fn, class... Args>future<typename result_o...原创 2020-04-04 00:02:05 · 1093 阅读 · 0 评论 -
What is a coroutine?
什么是协程随着coroutine ts正式进入c++20,c++已经进入协程时代了。c++20提供的无栈协程,拥有许多无与伦比的优越性,比如说没有传染性,可以与以前非协程风格的代码并存,再比如说不需要额外的调度器,总之是个好东西,我们首先需要知道,什么是协程?“协程”一词由两个词组成: “co” (cooperative ) 和 “routines” (functions)。协程是协作的功能...原创 2020-03-28 13:52:12 · 276 阅读 · 0 评论 -
为什么要在C ++ 11中使用“override”说明符?
如果您知道Java,那么您可能已经很熟悉Java了,这对您来说可能是完全简单的@Override annotation。如果您一直使用C / C ++进行编码,那么这可能是新的。您可能会问自己一个问题,为什么在不必要的时候为什么要放一个额外的说明符。您的代码将以相同的方式工作。虽然在大多数情况下,代码的行为是不会改变的,但在其他情况下(实际上是在犯错误时),使用override会阻止您检查错误的...翻译 2020-03-27 23:16:14 · 656 阅读 · 0 评论 -
Big-endian and Little-endian (大小端)
字节序(Endianness)在计算中,字节序是指数字的二进制表示形式中字节(或有时是位)的顺序。它也可以更一般地用于指代任何表示形式的内部排序,例如数字系统中的数字或日期的各个部分。在最常见的用法中,字节顺序表示多字节数字中字节的顺序。big-endian顺序将最高有效字节排在最前面,最低有效字节排在最后,而little-endian的顺序则正好相反。例如,考虑无符号十六进制数0x1234,...原创 2020-03-07 16:58:28 · 1136 阅读 · 0 评论 -
type_traits 类型萃取
一、 c++ traitstraits是c++模板编程中使用的一种技术,主要功能:把功能相同而参数不同的函数抽象出来,通过traits将不同的参数的相同属性提取出来,在函数中利用这些用traits提取的属性,使得函数对不同的参数表现一致。traits是一种特性萃取技术,它在Generic Programming中被广泛运用,常常被用于使不同的类型可以用于相同的操作,或者针对不同类型提供不...转载 2020-02-15 14:57:47 · 1544 阅读 · 0 评论 -
临时变量生命期
有关临时对象的生命周期有三种情况:一般情况:临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤。该完整表达式造成临时对象的产生。以及两个特殊情况凡含有表达式执行结果的临时性对象,应该存留到object的初始化操作完成为止。如果一个临时性对象被绑定于一个reference,对象将残留,直到被初始化之reference的生命结束,或直到临时对...原创 2020-02-09 18:37:16 · 569 阅读 · 0 评论 -
锁(Lock)、内存屏障(Memory barrier)与 缓存一致性( Cache coherence)
在应用层,关于锁的使用大家应该都很熟悉了,作用就是为了保护共享变量不被同时操作而导致无法预测的情况。然而深入到具体实现,锁仅仅只是锁定临界区吗?锁的实现其实还必须实现一个语义,也就是内存屏障。内存屏障主要用于防止指令重排而导致的无法预测的情况。代码经过编译器生成的指令并不一定都是按着我们原先的想法来生成的,可能经过优化等情况进行了指令的重排,然而这些重排在执行后的结果应当是一致的。其实及时编译器...原创 2020-02-07 21:27:04 · 7996 阅读 · 0 评论 -
Atomic Operations (standardized memory model)
C ++规范未引用任何特定的编译器,操作系统或CPU。它引用了 abstract machine 抽象机,它是对实际系统的概括。在语言规范中,程序员的工作是为抽象机编写代码。编译器的工作是在具体机器上实现该代码。通过严格按照规范进行编码,可以确定您的代码可以在不使用兼容C ++编译器的任何系统上进行编译和运行,而无论是现在还是50年后。C ++ 98 / C ++ 03规范中的抽象机基本上...翻译 2020-02-07 21:02:24 · 322 阅读 · 0 评论 -
constexpr关键字
constexpr是C++11引入的关键字,为什么在有const关键字的基础上要引入constexpr呢?它们二者有什么区别呢?简介C++编译时可确定常量表达式的结果,因此可在编译时优化。C++规范在一些地方要求使用常量表达式,如声明数组的维数。但常量表达式不允许包含函数调用或者对象构造。因此下述代码无效:int get_five() {return 5;}int some_value[...原创 2020-02-06 17:58:05 · 1553 阅读 · 0 评论 -
Linux进程同步机制-Futex
引子在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这个内核不一定能正确的运行使用glibc的程序",那futex是什么?和glibc又有什么关系呢?futex诞生之前在futex诞生之前,linux下的同步机制可以归为两类:用户态的同步机制 和 内核同步机制。 用户态的同步机制基本上就是利用原子指令实现的sp...原创 2020-02-04 19:50:46 · 1089 阅读 · 0 评论 -
C++ 类成员指针
1.成员指针简介成员指针是C++引入的一种新机制,它的申明方式和使用方式都与一般的指针有所不同。成员指针分为成员函数指针和数据成员指针。2. 成员函数指针在事件驱动和多线程应用中被广泛用于调用回调函数。在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数。在这样的应用中,如果不用成员指针,编程是非常困难的。成员函数指针的定义格式:成员函数返回类型 (类名::*指针名)(形...转载 2019-12-21 18:33:17 · 712 阅读 · 0 评论 -
SFINAE and enable_if
在C ++中将函数重载与模板混合时,必须考虑一个有趣的问题。模板的问题在于它们通常包含过多的内容,并且与重载混合使用时,结果可能令人惊讶:#include <iostream>void foo(unsigned i) { std::cout << "This is unsigned Function : " << i << "\n";}...原创 2019-12-21 16:59:10 · 506 阅读 · 0 评论 -
AOP(Aspect-oriented programming,面向切面编程)
概述面向切面的程序设计(Aspect-oriented programming,AOP)是CS计算机科学中的一种程序设计泛型,旨在将横切关注点与业务主体进行进一步分离,以提高程序代码的模块化程度。其可以通过预编译方式和运行期动态代理实现在不修改源码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可...翻译 2020-02-04 16:46:03 · 1744 阅读 · 0 评论 -
C++11 auto and decltype 以及新的函数声明语法
C++11 引入了几种新的类型推断,可以让你为那些编译器本来就应该知道的事实写更少的代码。当然,我们也需要在必要的时间帮助编译器或者其他开发人员,但是使用 C++ 11,你可以在那些无聊的工作上花费较少的时间,而关注于业务逻辑。我们从最明显的新特性:auto关键字开始讲起。auto的乐趣下面为那些没有阅读过C++0x 的第一篇文章的读者简要介绍下auto关键字。在 C++11 中,如...转载 2019-12-14 15:53:43 · 863 阅读 · 0 评论 -
断言(assert)的用法
我一直以为 assert 仅仅是个报错函数,事实上,它居然是个宏,并且作用并非"报错"。在经过对其进行一定了解之后,对其作用及用法有了一定的了解,assert() 的用法像是一种"契约式编程",在我的理解中,其表达的意思就是,程序在我的假设条件下,能够正常良好的运作,其实就相当于一个 if 语句:if(假设成立){ 程序正常运行;}else{ 报错&...转载 2019-12-02 23:33:45 · 458 阅读 · 0 评论 -
死锁产生的条件及其如何处理
一、原因与条件产生死锁的原因主要是:因为系统资源不足。 进程运行推进的顺序不合适。 资源分配不当等。发生死锁的四个必要条件:相互排斥:所涉及的资源必须不可共享;否则,将不会阻止进程在必要时使用资源。 保留并等待或部分分配:进程在等待其他(请求的)资源时必须保留已分配的资源。如果该进程必须在请求一个或多个新资源时释放其资源,则不会发生死锁,因为该进程不会阻止其他人使用它控制的资源...原创 2019-12-01 23:31:44 · 1934 阅读 · 0 评论 -
设计模式:创建型模式之单例模式(c++)
简介 单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 主要解决:一个全局使用的类频繁地创建与销毁。 何时使用:当您想控制实例数目,节省系统资源的时候。 如何解决:判断系统是否已经...原创 2019-11-24 17:59:03 · 193 阅读 · 0 评论 -
补码/反码、零扩展和符号位扩展(Zero extension and Sign extension)
众所周知,每种基本数据类型都有一个固定的位数,比如byte占8位,short占16位,int占32位等。正因如此,当把一个低精度的数据类型转成一个高精度的数据类型时,必然会涉及到如何扩展位数的问题。这里有两种解决方案:(1)补零扩展:填充一定位数的0。(2)补符号位扩展:填充一定位数的符号位(非负数填充0,负数填充1)。对于无符号类型(相当于都是非负数)与有符号类型中的非负数部分,这两种方法...原创 2019-11-13 23:41:38 · 28905 阅读 · 7 评论 -
typeinfo、typeid、 typeof 介绍
一、type_info类该类type_info保存有关类型的特定于实现的信息,包括类型的名称以及比较两种类型是否相等或排序顺序的方式。这是typeid运算符返回的类。#ifndef _TYPEINFO#define _TYPEINFO#include <exception>namespace std { class type_info { publ...原创 2019-11-10 19:21:03 · 4919 阅读 · 3 评论 -
const成员函数 / 函数名后面加const(Const member functions in C++ / “const” at end of function declaration? )
class Foo {public: int Bar(int random_arg) const { // code }};const在函数声明后用关键字表示的“常量函数”, 使该类函数更改class的成员变量成为编译器错误。但是,在函数内部可以读取类变量,但是在该函数内部进行写入将产生编译器错误。考虑这种“常量函数”的另一种方法是将类函数...原创 2019-11-10 18:01:22 · 449 阅读 · 0 评论 -
typedef struct vs struct definitions
在C ++中,只有细微的差别。这是C的遗留物,在其中有所作为。C语言标准(C89§3.1.2.3,C99§6.2.3和C11§6.2.3)为不同类别的标识符(包括标记标识符(用于struct/union/enum)和普通标识符(fortypedef和其他标识符))规定了单独的命名空间。。如果您只是说:struct Foo { ... };Foo x;您将得到一个编译器错误...翻译 2019-10-16 23:33:12 · 254 阅读 · 0 评论