自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(27)
  • 收藏
  • 关注

原创 C++ mutex

读写锁 shared_mutex若一个线程已获取独占性锁(通常不直接调用 lock() ,用 std::unique_lock 与 std::lock_guard 管理排他性锁定 ),则无其他线程能获取该锁(包括共享的)。仅当任何线程均未获取独占性锁时,共享锁能被多个线程获取(通过 std::shared_lock )。在一个线程内,同一时刻只能获取一个锁(共享或独占性)。mutable std::shared_mutex mutex_;unsigned int value_ = 0;// 多

2022-04-07 17:03:01 487

原创 C++ static关键字

**静态数据成员**类中数据成员的声明前加上static为该类的静态成员。类的静态数据成员在类实现文件中初始化,否则会出现未定义错误,且初始化时无需再用static关键字修饰,无论类被实例化多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享。**//单例模式实现template<typename T>class singleton{ public: template <typename... Args> static T* Ins

2022-04-02 17:41:41 1107

原创 C++一些内置宏

FILE :正在编译文件的文件名LINE :正在编译文件的行号DATE:编译时刻的日期字符串TIME:编译时刻的时间字符串STDC:当要求程序严格遵循ANSI C标准时该标识被赋值为1__cplusplus:当编写C++程序时该标识符被定义...

2021-10-12 15:39:46 394

转载 (C++)前置声明

前置声明在类的互包含中用到,还可以减少头文件的包含层次。像我们这样前置声明类A:class A;是一种不完整的声明,只要类B中没有执行需要了解类A的大小或者成员的操作,则这样的不完整声明允许声明指向A的指针和引用。而A a;是需要了解A的大小的,不然是不可能知道如果给类B分配内存大小的,因此不完整的前置声明就不行,必须要包含a.h来获得类A的大小,同时也要重新编译类B。再回到前面的问题,使用前置声明只允许的声明是指针或引用的一个原因是只要这个声明没有执行需要了解类A的大小或者成员的操作就可

2021-09-22 14:50:51 911

原创 (C++)纯虚函数

纯虚函数是在声明虚函数时被“初始化”为0的函数声明纯虚函数的一般形式:virtual 函数类型 函数名 (参数表列) = 0;纯虚函数没有函数体;最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;这是一个声明语句,最后应有分号。纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统: “在这里声明一个虚函数,留待派生类中定义”。在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。原文...

2021-09-07 11:55:51 336

原创 (C++) 头文件使用““与<>的区别

用 #include <filename.h> 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)

2021-08-06 15:15:08 328

原创 (C++) 条件编译

使用几个指令来有选择地对部分程序源代码进行编译,这个过程被称为条件编译。用法:1.#(ifdef + 标识符) … #else … #endif#ifdef (标识符) //可以理解为# if define 程序段1 //当标识符被定义过,编译程序段1 #else 程序段2 //否则编译程序段2 #endif 2.#(ifndef + 标识符) … #else … #endif#ifndef (标识符) //可以理解为# if not defin

2021-08-05 15:54:03 353

原创 C++ typedef 函数指针用法

作用:代码简化, 促进跨平台开发的目的。与#define区别:typedef 行为有点像 #define 宏,用其实际类型替代同义字。typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。示例:typedef int (*Myfunc)(char, char); //这种用法一般用在给函数定义别名的时候//上面的例子定义Myfunc 是一个函数指针, 函数类型是带两个char 参数, 返回类型为int //在分析这种形式的定义的时候可以用下面的方法: //先

2021-08-03 20:52:06 377

原创 C++多线程,同步与互斥

同步和互斥当有多个线程的时候,经常需要去同步(注:同步不是同时刻)这些线程以访问同一个数据或资源。例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。所谓同步,是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,

2020-11-26 11:11:38 331

原创 内存泄漏及危害

内存泄漏内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。危害长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。内存泄漏分类C/C++程序中一般我们关心两种方面的内存泄漏:堆内存泄漏(Heap leak)堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc /

2020-11-25 20:51:32 2615

原创 悬空指针与野指针

悬空指针一个指针的指向对象已被删除,那么就成了悬空指针。野指针指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。...

2020-11-25 20:45:18 188

原创 HTTP协议总结

HTTP协议HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件,图片文件,查询结果等)。HTTP是一个属于应用层的面向对象的协议。HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息

2020-10-19 23:27:25 184

原创 (C++)4种强制类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:static_castconst_castdynamic_castreinterpret_caststatic_caststatic_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换 void test() { double d = 12.34; int a = static_cast<int>(d); co

2020-10-18 14:42:44 297

原创 哈希表的实现

构造哈希对于构造哈希来说,主要包括:直接地址法取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B优点:简单、均匀缺点:需要事先知道关键字的分布情况适用场景:适合查找比较小且连续的情况平方取中法假设关键字为1234,对它平方就是1522756,抽取中间的3位227作为哈希地址; 再比如关键字为4321,对它平方就是18671041,抽取中间的3位671(或710)作为哈希地址使用场景:不知道关键字的分布,而位数又不是很大的情况除留余数设散列表中允许的地址数为m,取

2020-10-17 16:03:47 365

原创 (C++)构造函数和析构函数中的虚函数

原文引自《C++ Prime》中文版P497:构造派生类对象时首先运行基类构造函数初始化对象的基类部分。在执行基类构造函数是,对象的派生类部分是未初始化的。实际上,此时对象还不是一个派生类对象。撤销派生类对象时,首先撤销它的派生类部分,然后按照与构造顺序的逆序撤销它的基类部分。在这两种情况下,运行构造函数或析构函数的时候,对象都是不完整的。为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化。在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待。示例: class A

2020-10-16 21:31:30 301

原创 单例模式

单例模式单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。避免对资源的多重占用(比如写文件操作)。缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

2020-10-11 22:59:47 147

原创 程序内存分区中的栈与堆

栈栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。参考如下代码:int main(){ int b; //栈 char s[] = "abc"; //栈 char *p2; //栈}其中函数中定义的局部变量按照先后定义的顺序依次压入栈中,也就是说相邻变量的地址之间不会存在其它变量。栈的内存地址生长方向与堆相反,由高到底,所以后定义的变量地址低于先定义的变量,比如上面代码中变量 s 的地址小于变量 b 的地址,p2 地址小于 s 的

2020-10-10 20:45:40 351

原创 C++常对象和常成员函数

常对象常对象是指该对象在其生命周期内,其所有的数据成员的值都不能被改变;定义对象时加上关键字const,该对象就是常对象,其一般形式如下:类名 const 对象名[(实参类别)];或者const 类名 对象名[(实参类别)];形如:const CComplex num;需要特别说明的是:常对象只能调用常成员函数,不能调用普通成员函数 (除了隐式调用析构函数和构造函数),常成员函数是常对象的唯一对外接口;现在编译系统只检查函数的声明,只要发现调用了常对象的成员函数,而且该函数未被声明为c

2020-10-10 15:22:12 308

原创 C++11学习总结

新增基于范围的for循环类似Java中foreach语句,为遍历数组提供了很大方便。int nArr[5] = {1,2,3,4,5};for(int &x : nArr){ x *=2; //数组中每个元素倍乘}自动类型推断 auto编译器可以根据初始值自动推导出类型,但是不能用于函数传参以及数组类型的推导。无需提前声明定义的变量的数据类型。例如:auto i = 1; //编译器自动推断i为int类型这个功能在各种标准模板库容器中使用,作用更突出。如下:

2020-09-09 16:14:45 274

转载 C和C++内存模型

C分为四个区:堆,栈,静态全局变量区,常量区C++内存分为5个区域(堆栈全常代 ):堆 heap :由new分配的内存块,其释放编译器不去管,由我们程序自己控制(一个new对应一个delete)。如果程序员没有释放掉,在程序结束时OS会自动回收。涉及的问题:“缓冲区溢出”、“内存泄露”栈 stack :是那些编译器在需要时分配,在不需要时自动清除的存储区。存放局部变量、函数参数。存放在栈中的数据只在当前函数及下一层函数中有效,一旦函数返回了,这些数据也就自动释放了。全局/静态存储区 (.bss

2020-09-07 14:24:33 257

原创 static,virtual在一个类中的内存分布

1、static修饰符1)static修饰成员变量对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类)。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用。2)static修饰成员函数与普通的成员函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具

2020-09-07 12:45:24 438

原创 TCP协议

TCP连接过程三次握手1.Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。2.Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。3.Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将

2020-09-06 10:03:11 169

原创 互斥锁机制,互斥锁与读写锁区别

Linux的4种锁机制:互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒读写锁:rwlock,分为读锁和写锁。处于读操作时,可以允许多个线程同时获得读操作。但是同一时刻只能有一个线程可以获得写锁。其它获取写锁失败的线程都会进入睡眠状态,直到写锁释放时被唤醒。 注意:写锁会阻塞其它读写锁。当有一个线程获得写锁在写时,读锁也不能被其它线程获取;写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)。适用于读取数据的频率远

2020-09-04 12:25:57 6969

原创 进程与线程

基本概念:进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发;线程是操作系统可识别的最小执行和调度单位。每个线程都独自占用一个虚拟处理器:独自的寄存器组,指令计数器和处理器状态。每个线程完成不同的任务,但是共享同一地址空间(也就是同样的动态内存,映射文件,目标代码等等),打开的文件队列和其他内核资源。进程与线程区别:1.一个线程只能属于一个进程,而一个进程可以有多个线程,但至

2020-09-03 16:39:30 186

原创 2019/11/15

将数组A中的内容和数组B中的内容进行交换。(数组一样大)#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>int main(){ //将数组A中的内容和数组B中的内容进行交换。(数组一样大) int a[4] = { 1, 2, 3, 4 }; int b[4] = { 5,...

2019-11-16 21:49:19 251

原创 2019/11/10

交换两个整型变量#include<stdint.h>#include<stdlib.h>int main(){ int x , y ,t; printf("输入两个数:"); scanf("%d%d", &x, &y); t = x; x = y; y = t; printf("交换两个数:%d %d", x, y); s...

2019-11-11 22:44:42 157

原创 2019/11/10

输出乘法口诀表#include<stdio.h>#include<stdlib.h>int main(){int i, j;for (i = 1; i <= 9; i++){for (j = 1; j <= i; j++){printf("%d*%d=%d “, j, i, j*i);}printf(”\n");}system(“p...

2019-11-10 19:40:22 109

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除