c++11新特性-下

news2024/10/1 17:10:35

c++11的线程库可以跨平台使用。

原子性操作库(atomic)

不需要对原子类型变量进行加锁解锁操作,线程能够对原子类型变量互斥的访问。

atmoic<T> t; // 声明一个类型为T的原子类型变量t

在C++11中,原子类 型只能从其模板参数中进行构造,不允许原子类型进行拷贝构造、移动构造以及operator=

#include <atomic>
int main()
{
 atomic<int> a1(0);
 //atomic<int> a2(a1); // 编译失败
 atomic<int> a2(0);
 //a2 = a1; // 编译失败
 return 0;
}

thread的使用

仿函数配合thread使用

//仿函数配合thread使用
atomic<int> x = 0;
struct Add
{
	void operator()(int n)
	{
		for (int i = 0; i < n; ++i)
			++x;
	}
};
thread t1(Add(), 1000000);

 也可以使用匿名对象。

lambda配合thread使用

atomic<int> x = 0;
auto add = [&x](int n) {
	for (int i = 0; i < n; ++i)
		++x;
	};
thread t1(add, 1000000);
thread t2(add, 1000000);
cout << t1.get_id() << endl;
cout << t2.get_id() << endl;
t1.join();
t2.join();
cout << x << endl;

优化:

atomic<int> x = 0;
int m, n;
cin >> m >> n;
vector<thread> vthreads;
for (int i = 0; i < m; ++i)
{
	vthreads.push_back(thread([&x](int count) {
		for (int i = 0; i < count; ++i)
			++x;
	}, n));
}
for (auto& t : vthreads)
{
	cout << t.get_id() << ".join()" << endl;
	t.join();
}
cout << x << endl;
vector<thread> vthreads(m);
for (int i = 0; i < m; ++i)
{
	vthreads[i]=thread([&x](int count) {
		for (int i = 0; i < count; ++i)
			++x;
		}, n);
}

让两个线程分别打印奇偶数

int n = 10;
mutex mtx1, mtx2;
condition_variable cv1, cv2;
thread t1([&]() 
	{
	for (int i = 0; i < n; i += 2)
	{
		
		cout << this_thread::get_id() << ":" << i << endl;
		cv2.notify_one();
		cv1.wait((unique_lock<mutex>&)unique_lock<mutex>(mtx1));
	}
	});
thread t2([&]() {
	for (int i = 1; i < n; i += 2)
	{
		cv2.wait((unique_lock<mutex>&)unique_lock<mutex>(mtx2));
		cout << this_thread::get_id() << ":" << i << endl;
		cv1.notify_one();
	}
	});
t1.join();
t2.join();

throw可以抛出任意类型的对象。

catch(...)可以捕获任意类型的异常,问题是不知道异常错误是什么。

double Division(int a, int b)
{
 // 当b == 0时抛出异常
 if (b == 0)
 throw "Division by zero condition!";
 else 
 return ((double)a / (double)b);
}
 
void Func()
{
 int len, time;
 cin >> len >> time;
 cout << Division(len, time) << endl;
}
int main()
{
 try {
 Func();
 }
 catch (const char* errmsg) {
 cout << errmsg << endl;
 }
 catch(...){
 cout<<"unkown exception"<<endl; 
 }
 
 return 0;
}

智能指针

template<class T>
class SmartPtr
{
public:
	SmartPtr(T* ptr)
		:_ptr(ptr)
	{}
	~SmartPtr()
	{
		if (_ptr)
		{
			cout << "delete: " << _ptr << endl;
			delete _ptr;
		}
	}
private:
	T* _ptr;
};

RAII是一种托管资源的方式,智能指针是依靠这种RAII实现的。

C++98  auto_ptr

将管理权转移

缺陷:ap2=ap1时,ap1将悬空,访问就会报错。

auto_ptr<int> ap1(new int);
auto_ptr<int> ap2 = ap1;

C++11 unique_ptr

缺陷:无法应对需要拷贝的场景。

unique_ptr<int> ap1(new int);

C++11 shared_ptr

namespace sp
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr)
			:_ptr(ptr)
			,_pcount(new int(1))
		{}
		shared_ptr(shared_ptr<T>& sp)
			:_ptr(sp._str)
			, _pcount(new int(1))
		{
			++(*_pcount);
		}
		
		~shared_ptr()
		{
			if (--(*_pcount)==0&&_ptr)
			{
				cout << "delete: " << _ptr << endl;
				delete _ptr;
				_ptr = nullptr;
			}
		}
	private:
		T* _ptr;
		int* _pcount;
	};
}
//sp1=sp4
		shared_ptr<T>& operator=(shared_ptr<T>& sp)
		{
			if (this != &sp)
			{
				if (--(*_pcount) == 0)
				{
					delete _pcount;
					delete _ptr;
				}
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
			}
			return *this;
		}

引用计数为0时才能对_ptr进行释放,否则会发生内存泄漏。

++操作最终会被翻译为3条汇编指令。

namespace sp
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr)
			:_ptr(ptr)
			,_pcount(new int(1))
			,_pmtx(new mutex)
		{}
		shared_ptr(shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			,_pmtx(sp._pmtx)
		{
			//++(*_pcount);
			add_ref_count();
		}
		void add_ref_count()
		{
			_pmtx.lock();
			++(*_pcount);
			_pmtx.unlock();
		}
		void release()
		{
			bool flag = true;
			_pmtx.lock();
			if (--(*_pcount) == 0 && _ptr)
			{
				cout << "delete: " << _ptr << endl;
				delete _ptr;
				_ptr = nullptr;
				delete _pcount;
				_pcount = nullptr;
				flag = true;
			}
			_pmtx.unlock();
			if (flag == true)
			{
				delete _pmtx;
				_ptrx = nullptr;
			}
		}
		//sp1=sp4
		shared_ptr<T>& operator=(shared_ptr<T>& sp)
		{
			if (this != &sp)
			{
				release();
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
			}
			return *this;
		}
		~shared_ptr()
		{
			release();
		}
	private:
		T* _ptr;
		int* _pcount;
		mutex _pmtx;
	};
}

shared_ptr:不能解决循环引用的问题

weak_ptr: 可以辅助shared_ptr解决循环引用的问题,严格来说weak_ptr不是智能指针。

template<class T>
class weak_ptr
{
public:
	weak_ptr() = default;
	weak_ptr(const sp::shared_ptr<T>& sp)
		:_ptr(sp.get_ptr())
	{}
	weak_ptr<T>& operator=(const shared_ptr<T>& sp)
	{
		_ptr = sp.get_ptr();
		return *this;
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
	T* get_ptr() const
	{
		return _ptr;
	}
private:
	T* _ptr;
};
struct ListNode
{
	int val;
	sp::shared_ptr<ListNode> _spnext;
	sp::shared_ptr<ListNode> _spprev;
	ListNode()
		:val(0)
		, _spnext(nullptr)
		, _spprev(nullptr)
	{}
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};
sp::shared_ptr<ListNode> spn1(new ListNode);
sp::shared_ptr<ListNode> spn2(new ListNode);
spn1->_spnext = spn2;
spn2->_spprev = spn1;

智能指针是RAII设计思想的体现

本质上RAII就是借助了构造函数和析构函数,构造函数和析构函数的特点都是自动调用。

使用RAII思想设计的锁管理守卫

template<class lock>
class LockGuard
{
public:
	LockGuard(Lock& lock)
		:_lk(lock)
	{
		_lk.lock();
	}
	~LockGuard()
	{
		cout << "解锁" << endl;
		_lk.unlock();
	}
private:
	Lock& _lk;
};

如何实现,创建出的类只能在堆上?

class HeapOnly
{
public:
	static HeapOnly* GetObj()
	{
		return new HeapOnly;
	}
	HeapOnly(const HeapOnly&) = delete;
private:
	HeapOnly()
	{}

};
shared_ptr<HeapOnly> sp1(HeapOnly::GetObj());
shared_ptr<HeapOnly> sp2(HeapOnly::GetObj());

如何实现,创建出的类只能在栈上?

class StackOnly
{
public:
	static StackOnly GetObj()
	{
		return StackOnly();//传值返回需要调用拷贝构造
	}
private:
	StackOnly() {}
	
};
StackOnly so = StackOnly::GetObj();
StackOnly* p = new StackOnly;//operator new+ 构造函数

构造函数私有化后,这个类就不能被继承了。

单例模式

简单的单例模式

懒汉模式:

class Singleton
{
public:
	static Singleton* GetInstance()
	{
        //sleep(1000);
        //_mtx.lock();
        if(_pinst==nullptr)
    {
        unique_lock<mutex> lock(_mtx);
		if (_pinst == nullptr)
		{
			_pinst = new Singleton;
		}
    }
        //_mtx.unlock();
		return _pinst;
	}
private:
	Singleton() {}
	Singleton(const Singleton& s) = delete;
	static Singleton* _pinst;
    static mutex _mtx;
};
Singleton* Singleton::_pinst = nullptr;
mutex Singleton::_mtx;

第一个if是为了防止对象已经创建好之后2,还需要每次加锁,造成锁的浪费

第二个if是防止非原子操作导致多个线程一起写

饿汉模式

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return &_inst;
	}
	Singleton(const Singleton&) = delete;
private:
	Singleton()
	{}
	static Singleton _inst;
};

总结:

1.懒汉模式需要考虑线程安全和释放的问题,实现复杂而饿汉模式实现简单

2.懒汉模式是懒加载模式需要再初始化创建对象,不会影响程序启动,

饿汉模式程序启动时就创建实例化对象,会导致程序变慢

3.如何有多个单例类,假设有依赖关系(B依赖A)要求A单例先创建初始化,B单例在创建初始化,则不能用饿汉模式,饿汉模式无法保证创建初始化顺序,懒汉模式可以手动控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2182786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【规控+slam】探索建图方案及代码分享

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言背景建图描述SLAM定位+感知数据标记构建地图自动探索建图规划方法一:手动遥控探索建图算法步骤方法二:手动给定目标点探索建图算法原理方法三:f…

VMware虚拟机连接公网,和WindTerm

一、项目名称 vmware虚拟机连接公网和windterm 二、项目背景 需求1&#xff1a;windows物理机&#xff0c;安装了vmware虚拟机&#xff0c;需要访问公网资源&#xff0c;比如云服务商的yum仓库&#xff0c;国内镜像加速站的容器镜像&#xff0c;http/https资源。 需求2&#xf…

Hive数仓操作(八)

一、Hive中的分桶表 1. 分桶表的概念 分桶表是Hive中一种用于提升查询效率的表类型。分桶指的是根据指定列的哈希值将数据划分到不同的文件&#xff08;桶&#xff09;中。 2. 分桶表的原理 哈希分桶&#xff1a;根据分桶列计算哈希值&#xff0c;对哈希值取模&#xff0c;将…

【漏洞复现】JeecgBoot 积木报表 queryFieldBySql sql注入漏洞

》》》产品描述《《《 积木报表&#xff0c;是一款免费的企业级Web报表工具&#xff0c;像搭建积木一样在线设计报表!功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等! 》》》漏洞描述《《《 JeecgBoot 积木报表 queryFieldBySq| 接口存在一个 SQL 注入漏洞&…

Web和UE5像素流送、通信教程

一、web端配置 首先打开Github地址&#xff1a;https://github.com/EpicGamesExt/PixelStreamingInfrastructure 找到自己虚幻引擎对应版本的项目并下载下来&#xff0c;我这里用的是5.3。 打开项目找到PixelStreamingInfrastructure-master > Frontend > implementat…

NodeJS下载、安装及环境配置教程,内容详实

文章目录 概述关于本文NodeJS介绍 安装步骤 概述 关于本文 本文讲解如何在Windows系统中安装NodeJS并配置相关环境。 NodeJS介绍 Node.js&#xff08;通常简称为Node&#xff09;是一个开源、跨平台的JavaScript运行时环境&#xff0c;它允许开发者在服务器端运行JavaScrip…

【PyTorch】图像分割

图像分割是什么 Image Segmentation 将图像每一个像素分类 图像分割分类 超像素分割&#xff1a;少量超像素代替大量像素&#xff0c;常用于图像预处理语义分割&#xff1a;逐像素分类&#xff0c;无法区分个体实例分割&#xff1a;对个体目标进行分割全景分割&#xff1a;…

Simulink仿真中get_param函数用法

目录 语法 说明 示例 获取模块参数值和模型参数值 获取根参数名称和值 获取模型参数名称和值 获取模块列表和参数值 使用模块句柄获取模块参数值 显示模型中所有模块的模块类型 获取封装参数、Simulink 对象、模块图或注释的选项列表 获取封装参数的计算值 get_para…

如何用TorchAO优化PyTorch模型:看得见的性能提升

你有没有在训练PyTorch模型时,遇到过速度慢、内存占用高的问题?不管你是研究模型优化,还是追求性能极致的开发者,TorchAO可能正是你需要的工具。今天我们来聊聊这个PyTorch原生的架构优化工具,看看它是如何帮助你优化模型的,并且提升整体性能。 TorchAO是什么? Tor…

基于JAVA+SpringBoot+Vue的社区养老服务平台

基于JAVASpringBootVue的社区养老服务平台 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈…

脸爱云管理系统存在任意文件上传漏洞

漏洞描述 脸爱云一脸通智慧管理平台是一套功能强大、运行稳定、操作简单方便、用户界面美观的一脸通系统。该平台整合了人脸识别技术和智能化解决方案&#xff0c;可以实现识别和管理个体身份&#xff0c;为各种场景提供便捷的身份验证和管理功能。其存在任意文件上传漏洞&…

数值计算的程序设计问题举例

### 数值计算的程序设计问题 #### 1. 结构静力分析计算 **涉及领域**&#xff1a;工程力学、建筑工程 **主要问题**&#xff1a;线性代数方程组&#xff08;Linear Algebraic Equations&#xff09; **解释说明**&#xff1a; 在结构静力分析中&#xff0c;我们需要解决复杂的…

C++第五讲(2):STL--string--string的模拟实现+知识加餐

C第五讲&#xff08;2&#xff09;&#xff1a;STL--string--string的模拟实现知识加餐 1.string的模拟实现1.1string.h头文件 -- string类的声明1.2string.cpp源文件 -- string的具体实现1.3test.cpp源文件 -- string模拟实现的测试 2.知识补充1&#xff1a;swap3.知识补充2&a…

IDEA几大常用AI插件

文章目录 前言列表GPT中文版TalkXBito AIIDEA自带的AI 前言 最近AI、GPT特别火&#xff0c;IDEA里面又有一堆插件支持GPT&#xff0c;所以做个专题比较一下各个GPT插件 列表 先看idea的plugins里支持哪些&#xff0c;搜索“GPT”之后得到的&#xff0c;我用下来感觉第一第二和…

【Iceberg分析】调研Iceberg中表的原地演变

调研Iceberg中表的原地演变 文章目录 调研Iceberg中表的原地演变原生非分区表文件关系图表的原地演变之表schema演变新增字段new_column文件关系变化图为新增字段写入数据文件关系变化图删除新增字段文件关系变化图新增字段new_column2文件关系变化图删除数据文件关系变化图 原…

无人机之数据提取篇

一、无人机平台与传感器 无人机是进行数据采集的基础设施&#xff0c;其稳定性、可靠性、灵活性和负载能力直接影响到数据采集的效果。根据实际需求&#xff0c;需选择适合的无人机类型&#xff0c;如固定翼无人机适合大范围、长时间的数据采集&#xff0c;而多旋翼无人机则更适…

从Fast-UMI到Diff-Control:分别改进UMI的硬件、UMI所用的扩散策略

前言 24年9.28日下午&#xff0c;微信上的好友丁研究员和我说 hi 周总&#xff0c;我们基于umi改进了一下——弄了一个用户友好的采集系统(当然&#xff0c;现在这个版本还比较初级 后续不断迭代)项目网站为&#xff1a;https://fastumi.com/ 技术报告见&#xff1a;https://…

docker和kafka连接Topic失败处理措施

使用 docker 镜像部署一套单节点的 Zookeeper Kafka&#xff0c;但是一直Java却连不上一些处理思路。 为了提高部署效率&#xff0c;这里提供一个简单可启动的docker-compose。 version: "3.3" services:zookeeper:image: zookeeper:3.5.5restart: alwayscontainer…

Global Illumination_VXGI(VCT) Deep Optimizations

之前针对RSM和LPV优化技术介绍后&#xff0c;我们可以看出来一个大致的思路的&#xff1a;就是减少计算量提升最大&#xff0c;因此VXGI的优化思路和之前两种算法几乎一样&#xff0c;之前也实现过Global Illumination_Voxel Global Illumintaion (VXGI)有兴趣的可以去简单了解…

软件系统可视化建设方案书(word原件)

第 一 章 系统总体设计 1.1 总体架构 1.1.1 系统拓扑 1.1.2 系统组成 1.2 设计概述 1.3 平台系统功能 1.3.1 总部数据看板 1.3.2 项目部数据看板 1.3.3 视频联网系统 1.3.4 实名制考勤系统 1.3.5 安全生产系统 1.3.6 塔吊安全监控子系统 1.3.7 施工升降机安全监控管系统 1.3.8 …