![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 71
逆风路途
这个作者很懒,什么都没留下…
展开
-
explicit
explicit是C++中用于修饰类的构造函数的一个关键字,一般用于修饰只有一个参数类的构造函数。它的作用是防止隐式转换发生,使得只有显式调用才能进行类对象的转换。当声明了一个使用了explicit关键字的构造函数时,编译器将不再支持隐式转换,需要使用强制类型转换或者显式地调用构造函数来完成转换。跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。原创 2024-05-05 15:04:26 · 394 阅读 · 0 评论 -
C++11中的std::function和std::bind
C++语言中有几种:函数、函数指针、lambda 表达式、bind 创建的对象以及重载了函数调用运算符的类。和其他对象一样,也有类型。两个不同类型的可调用对象可能共享同一种调用形式指明了调用返回的类型以及传递给调用的实参类型。一种调用形式对应一个函数类型,例如:int (int, int) 是一个函数类型,它接受两个int,返回一个int。C++中虽然都有一个比较统一的操作形式,但是定义方法五花八门,这样就导致使用统一的方式保存可调用对象或者传递可调用对象时,会十分繁琐。原创 2024-04-26 16:58:01 · 890 阅读 · 0 评论 -
c++11 call_once 和 once_flag
std::call_once 和 std::once_flag 是 C++11 中引入的线程安全的函数和类型,用于确保某个函数只被调用一次。使用std::call_once时,需要先创建一个std::once_flag对象,并将其作为参数传递给std::call_once函数。当多个线程同时调用std::call_once时,只有一个线程会执行func函数,其他线程会被阻塞,直到func函数执行完毕。原创 2024-04-26 16:20:33 · 955 阅读 · 2 评论 -
C++Lambda表达式介绍
C11中引入了Lambda表达式,Lambda表达式是一种匿名函数,它可以在需要函数的地方直接定义和使用,而无需显式地定义一个函数。原创 2024-02-26 21:05:11 · 820 阅读 · 0 评论 -
C++多线程同步之条件变量(condition_variable)
在C++11中,使用条件变量(condition_variable)可以实现多个线程间的同步操作;当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线程才会被唤醒。条件变量用于阻塞一个或多个线程,直到某个线程修改线程间的共享变量,并通过condition_variable通知其余阻塞线程。从而使得已阻塞的线程可以继续处理后续的操作。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:1、一个线程因等待"条件变量的条件成立"而挂起;原创 2024-02-26 20:45:11 · 1032 阅读 · 0 评论 -
消息队列介绍
C++中的消息队列是一种数据结构或容器,用于在多个线程之间进行异步通信和数据传输。它基于先进先出(FIFO)的原则,即最先发送的消息最先被接收和处理。原创 2023-08-06 17:29:16 · 218 阅读 · 0 评论 -
C++动态加载 插件
动态加载(Dynamic Loading)是指在程序运行时,根据需要动态地加载和链接代码或资源。动态加载的主要目的是实现程序的灵活性和可扩展性,以及减少内存消耗和启动时间。通过动态加载,程序可以根据运行时的需求加载特定的模块、库或插件,而不需要将所有代码和资源都打包在一起。这样可以实现模块化设计,减少程序的体积,以及在需要时进行动态升级和扩展。在C++中,常见的动态加载方式是使用动态链接库(Dynamic Link Library,DLL)或共享对象(Shared Object,SO)文件。原创 2023-08-06 17:14:44 · 757 阅读 · 0 评论 -
C++友元函数,友元类
友元函数是在C++中用来访问另一个类的私有成员的一种机制。通过将函数声明为友元函数,可以使该函数能够访问类中的私有成员,即使它不是类的成员函数或者成员。原创 2023-08-06 17:02:53 · 944 阅读 · 0 评论 -
C++符号导出问题
在Windows下生成DLL时,可以使用dll_export来将需要对外的符号导出来。__declspec在Linux中,默认是所有的符号都是导出的,只有使用了相应的attribute才能将不想导出的(库内部使用的)的符号隐藏起来。visibilityDLLEXPORT是一个宏定义,通常用于C/C++语言中的动态链接库(DLL)的开发。DLLEXPORT的作用是在编译动态库时,将函数或变量标记为可导出,以便其他程序可以调用这些函数或变量。原创 2023-08-06 16:55:34 · 620 阅读 · 0 评论 -
设计模式类型及原则
设计模式是一种被广泛应用于面向对象编程的设计思想,可以帮助解决软件开发中的一些通用问题。在这个过程中,设计模式的设计原则是指,遵循一些通用的设计准则,以确保我们能够创建出良好的设计,使我们的代码能够具有良好的可维护性、可读性、可扩展性和可重用性。原创 2023-04-24 20:41:56 · 375 阅读 · 0 评论 -
设计模式之单例模式
【代码】设计模式之单例模式。原创 2023-05-09 21:38:46 · 51 阅读 · 0 评论 -
设计模式之工厂模式
工厂模式是一种常用的设计模式,它主要用来解决对象的创建问题,在不暴露对象创建的细节的同时,为客户端提供统一的接口来创建对象。在工厂模式中,客户端不再需要知道创建对象的具体细节,只需要知道需要什么对象即可。原创 2023-04-24 20:51:10 · 425 阅读 · 0 评论 -
设计模式之观察者模式
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,它会通知所有观察者对象,使它们能够自动更新自己。原创 2023-05-09 21:30:32 · 825 阅读 · 1 评论 -
设计模式之组合模式
组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表现“部分-整体”的层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。组合模式的核心思想是:将单个对象和组合对象放在一个统一的结构中,从而使得客户端能够以一致的方式处理它们。在组合模式中,客户端只需要面向抽象构件编程,而不必关心具体的叶子节点或容器节点的实现细节。原创 2023-05-09 21:09:16 · 1018 阅读 · 0 评论 -
设计模式之策略模式
策略模式(Strategy Pattern)是一种行为型设计模式。它定义了一系列算法,将每个算法都封装起来,并且使它们之间可以替换。策略模式让算法的变化独立于使用算法的客户端,即让算法变化不会影响到使用算法的客户端。这种模式的目的是在运行时根根据不同的情况选择不同的算法或行为。策略模式将一个算法的行为与其它算法分离开来,使它们可以独立地变化和替换。原创 2023-05-09 21:19:11 · 547 阅读 · 0 评论 -
const
将const修饰的“成员函数”称之为const成员函数。this指针的类型是:类类型* const this,即成员函数中,不能修改this指针,但是其所指向对象的成员变量可以被修改,const修饰类成员函数,实际上就是将this限定为:const 类类型 * const this,表明在该成员函数中不能对调用对象的任何成员进行修改,起到保护对象的作用。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。原创 2023-05-28 18:22:15 · 2161 阅读 · 0 评论 -
static
可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数;1. 静态成员之间可以相互访问,包括静态成员函数访问静态成员变量和访问静态成员函数。静态成员函数能访问静态(函数、变量),静态成员函数不能访问非静态。2. 非静态成员函数可以任意的访问静态成员函数和静态成员变量。3. 静态成员函数不能访问非静态成员函数和非静态成员变量。用于函数体的内部修饰变量,这种变量的生存期长于该函数。准确的说,静态函数跟静态全局变量的作用类似。静态成员函数不能访问非静态。非静态可以访问静态。原创 2023-05-28 18:20:19 · 1602 阅读 · 0 评论 -
C++菱形继承
菱形继承:指有一个基类被两个不同的类所继承,且存在一个类继承于这两个类而形成的一种菱形关系,故称菱形继承。原创 2023-07-10 10:03:27 · 481 阅读 · 0 评论 -
C++协变(covariant)
C++中,协变(covariant)是指派生类(子类)中的返回类型可以是基类(父类)中返回类型的子类型。换句话说,如果一个虚函数在基类中返回的是基类类型的指针或引用,那么派生类可以重写该虚函数并返回基类类型的子类类型的指针或引用。协变在C++中是通过使用返回类型协变(return type covariance)来实现的。返回类型协变是指派生类中重写的虚函数可以具有比基类更具体的返回类型。这种协变的能力使得在使用多态时更加灵活,可以根据具体的派生类返回不同的子类型,而不需要进行显式的类型转换。原创 2023-07-09 15:40:22 · 1315 阅读 · 1 评论 -
C++强制类型转换
此外,由于dynamic_cast是在运行时进行类型检查的,因此它的效率也受到了硬件的限制,例如处理器的速度和内存带宽等。当我们需要将一个 const 对象或指针传递给一个不接受 const 参数的函数时,可以使用 const_cast 将其 const属性去掉,从而使其能够被接受。如果使用 const_cast 去除常量性后,没有实际修改对象的值,那么最好使用 static_cast,因为 static_cast更加安全。它会在转换时进行类型检查,如果转换不合法,则返回空指针或引用,而不会出现类型错误。原创 2023-05-28 17:56:21 · 1527 阅读 · 0 评论 -
C++11 override和final关键字
override关键字用于显示地表明派生类中的成员函数覆盖了基类中的虚函数。当派生类中的函数与基类中的虚函数签名不同或者没有使用override关键字时,编译器会给出警告或错误提示。这样可以避免因为函数签名不同而无法正确覆盖基类中的虚函数,从而导致程序运行时的错误。如果在一个虚函数上使用了final关键字,那么任何派生类都无法再对该函数进行重载。当 final 用于成员函数上时,它表示该函数不能被重写。当 final 用于虚函数上时,它表示该虚函数不能被覆盖。原创 2023-05-28 15:20:02 · 1416 阅读 · 0 评论 -
c++11 =delete、=default
C++11中的=delete和=default是两个C++关键字,是两个新特性,它们都用于显式地声明或定义类的特殊成员函数。它们的主要作用是在类的定义中控制函数的生成和删除。需要注意的是,=delete和=default只能用于特殊成员函数(析构函数、拷贝构造函数、拷贝赋值函数、移动构造函数和移动赋值函数),而且不能同时在同一个函数声明中使用。原创 2023-05-29 21:39:57 · 217 阅读 · 0 评论 -
C++内存分类
初始化的数据段,通常称为数据段,是程序的虚拟地址空间的一部分,它包含有程序员初始化的全局变量和静态变量,可以进一步划分为只读区域和读写区域。未初始化的数据段,通常称为bss段,这个段的数据在程序开始之前有内核初始化为0,包含所有初始化为0和没有显示初始化的全局变量和静态变量。每当调用一个函数时,返回到的地址和关于调用者环境的某些信息的地址,比如一些机器寄存器,就会被保存在栈中。,通常代码段是共享的,对于经常执行的程序,只有一个副本需要存储在内存中,代码段是只读的,以防止程序以外修改指令。原创 2023-05-28 18:07:19 · 1008 阅读 · 0 评论 -
内存对齐原则
结构体第一个数据成员放在offset为0的地方,后面每个成员相对于结构体首地址的偏移量(offset)都是成员大小(该变量类型所占字节)的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储(struct a里存有struct b,b里有char 、int 、double等元素,那b应该从8的整数倍开始存储);与成员函数和静态成员无关,即普通成员函数、静态成员函数、静态成员变量。原创 2023-05-28 18:12:36 · 2000 阅读 · 0 评论 -
联合体和位域的结合
总的来说,联合体和位域的结合使用可以在某些场景下提供更高效和灵活的内存管理方式。然而,需要注意跨平台兼容性、可读性和可维护性,以及位域的范围限制。位域成员变量的类型必须是整型(signed或unsigned)或枚举类型。位域是一种用于在一个字节或更小的空间中存储多个标志位或数据的机制。位域使用冒号 : 来声明成员变量所占用的位数。原创 2023-07-09 15:39:43 · 508 阅读 · 0 评论 -
C++ malloc & free、new & delete
malloc函数用于动态分配内存,它的原型为。它返回一个指向连续内存块的指针,该内存块的大小至少为size字节,如果无法分配请求的大小,则返回NULL。free函数用于释放动态分配的内存,它的原型为。它将指向动态分配的内存块的指针ptr作为参数,并将该内存块释放,使其可供后续的动态分配。原创 2023-05-28 18:06:13 · 1551 阅读 · 0 评论 -
内存泄漏、指针越界
内存泄漏是指在程序运行时,分配给程序使用的内存空间没有被及时地释放回系统,一直占用着系统资源,导致系统内存不足,最终导致系统性能下降或者程序崩溃等问题。在内存申请和释放过程中,可能会存在一些较小的内存块无法被正确回收,这些小的内存块会一直存在于程序中,从而导致内存泄漏。内存泄漏会导致程序占用大量的内存资源,并且这些内存无法被程序释放,从而导致内存资源的浪费。内存泄漏指的是程序在动态分配内存后没有正确释放,导致系统内存资源的浪费,最终可能导致程序崩溃。动态数组的边界问题容易导致内存泄漏问题。原创 2023-05-28 18:04:50 · 2054 阅读 · 0 评论 -
堆(heap)、栈(stack)
堆可以分为最大堆和最小堆,其中最大堆要求父节点的键值大于或等于其子节点的键值,最小堆则要求父节点的键值小于或等于其子节点的键值。栈是一种“后进先出”(Last-In-First-Out,LIFO)的数据结构,它是一种线性表,只允许在表的一端进行插入和删除数据。在栈上分配的内存由系统自动管理,无需开发人员手动管理,但是栈的内存空间通常较小,而堆可以灵活地分配和释放内存空间,但需要手动管理内存。是静态分配的内存区域,大小在程序编译时已经确定,栈中的元素是自动分配的,生命周期是函数执行期间。原创 2023-05-28 18:11:13 · 2264 阅读 · 0 评论 -
C++智能指针
动态分配的内存不是通过 new 关键字分配的,而是通过其他方式分配的,例如 mmap、malloc 等。动态分配的内存需要在释放之前执行一些额外的操作,例如释放资源时需要关闭文件句柄、释放锁等。示例代码:delete p;// 使用 reset 函数传递删除器 p . reset(new int(20) , my_deleter);return 0;} /*原创 2023-05-28 16:37:39 · 2002 阅读 · 0 评论 -
C++无锁队列
C++无锁队列是一种多线程编程技术,它可以在不使用锁的情况下实现线程安全的队列。它可以提高多线程程序的性能。无锁队列的主要思想是让多个线程同时访问队列,而不需要使用锁来保护共享资源。这可以避免锁竞争和死锁等问题,从而提高程序的效率。原创 2023-05-28 15:39:56 · 4503 阅读 · 6 评论 -
C++无锁队列之环形队列-数组实现
C++ 的环形队列是一种特殊的队列结构,它可以避免队列的内存空间浪费,同时提高队列的性能。环形队列通常使用数组或者链表来实现,本文将介绍基于数组实现的环形队列。原创 2023-06-01 15:40:02 · 441 阅读 · 0 评论 -
C++11之atomic原子操作
所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。原子操作保证了对数据的访问只有未开始和已完成两种状态,不会访问到中间状态,但我们访问数据一般是需要特定顺序的,比如想读取写入后的最新数据,原子操作函数是支持控制读写顺序的,即带有一个数据同步内存模型参数std::memory_order,用于对同一时间的读写操作进行排序。: 顺序一致性模型,这是C++11原子操作的默认模型;原创 2023-05-28 17:29:32 · 2591 阅读 · 0 评论 -
C++11强类型枚举
综上所述,虽然强类型枚举在类型安全性等方面具有优势,但在编程复杂度、转换、兼容性和空间占用等方面存在一些缺点。强类型枚举是一种更加类型安全的枚举类型,相对于传统的枚举类型,强类型枚举可以提供更好的安全性和可读性。C++11引入了强类型枚举(enum class),也称为枚举类。原创 2023-05-27 18:19:08 · 2613 阅读 · 0 评论 -
C++位运算符
C++中的位运算符用于对二进制数据进行操作。原创 2023-05-27 18:14:37 · 740 阅读 · 0 评论 -
C++多线程
有操作系统相关知识的应该知道,线程是轻量级的进程,每个线程可以独立的运行不同的指令序列,但是线程不独立的拥有资源,依赖于创建它的进程而存在。简单地讲,unique_lock 是 lock_guard 的升级加强版,它具有 lock_guard 的所有功能,同时又具有其他很多方法,使用起来更强灵活方便,能够应对更复杂的锁定需要。condition_variable是一个类,这个类既有构造函数也有析构函数,使用时需要构造对应的condition_variable对象,调用对象相应的函数来实现上面的功能。原创 2023-05-28 17:37:58 · 2087 阅读 · 0 评论 -
C++多进程
有操作系统相关知识的应该知道,线程是轻量级的进程,每个线程可以独立的运行不同的指令序列,但是线程不独立的拥有资源,依赖于创建它的进程而存在。也就是说,同一进程中的多个线程共享相同的地址空间,可以访问进程中的大部分数据,指针和引用可以在线程间进行传递。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。共享内存:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题;管道,通常指无名管道,管道是最简单,效率最差的一种通信方式,不适合进程间频繁的交换数据。原创 2023-05-28 17:39:05 · 2006 阅读 · 0 评论 -
C++死锁
线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。该算法的核心思想是将系统中的资源分为多个类别,并且在分配资源时使用贪心的策略,确保可以满足所有进程的需求,并且不会造成死锁或资源耗尽等问题。去破坏产生死锁的四个必要条件中的一个或几个来预防死锁的产生。原创 2023-05-28 17:42:50 · 2252 阅读 · 0 评论 -
C++虚假唤醒
当生产者的数量(PRODUCTER_NUM)大于1时,无论是使用notify_one,或者是notify_all都会发生虚假唤醒,当多个生产者使用notify_one时,多个线程被唤醒,有可能其中一个处理的特别快,将所有的数据都处理完毕,那么接下来被唤醒的线程都无数据可处理。当使用notify_all通知消费线程时,会发生虚假唤醒,会有多个消费者线程收到信号被唤醒,当一个线程被唤醒之前,可能其他线程先被唤醒先持有锁,将产品消耗掉。多个线程在等待同一个条件变量时,其中一个线程被误唤醒,导致其他线程也被唤醒。原创 2023-05-28 17:43:02 · 3513 阅读 · 0 评论 -
TCP、UDP
原创 2023-05-28 16:55:38 · 46 阅读 · 0 评论 -
三次握手、四次挥手
原创 2023-05-28 16:48:45 · 33 阅读 · 0 评论