智能指针,c++11,单例,类型转换

c++11
unique_ptr
防拷贝

shared_ptr / weak_ptr:

引用计数,支持拷贝

面试

手写shared_ptr

各种ptr的特性对比,  不会问定制删除器和weak_ptr,但是问shared_ptr时,可以往这边延展.

单例

保证一写数据在一个进程中,只有一份,并且方便访问修改.

饿汉模式

在main函数之前就创建了对象

#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include <time.h>
using namespace std;

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return _ins;
	}

	void Add(const string& str)
	{
		_mtx.lock();
		_v.push_back(str);
		_mtx.unlock();
	}

	void Print()
	{
		_mtx.lock();
		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;
		_mtx.unlock();
	}
private:
	//限制类外面随意创建对象
	Singleton() 
	{}
private:
	mutex _mtx;
	vector<string> _v;	//想让vector的数据,在全局只有唯一一份
	static Singleton* _ins;
};

Singleton* Singleton::_ins = new Singleton;

int main()
{
	//Singleton s1;
	//static Singleton s2;
	Singleton::GetInstance()->Add("张三" );
	Singleton::GetInstance()->Add("李四");
	Singleton::GetInstance()->Print();

	int n = 10;
	thread t1([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t1线程" + to_string(rand()));	//添加随机数
		}
	});
	thread t2([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t2线程" + to_string(rand()));	//添加随机数
		}
	});

	t1.join();
	t2.join();
	Singleton::GetInstance()->Print();

	return 0;
}

张三
李四

张三
李四
t1线程41
t1线程18467
t1线程6334
t1线程26500
t2线程41
t2线程18467
t2线程6334
t1线程19169
t1线程15724
t1线程11478
t1线程29358
t2线程26500
t2线程19169
t2线程15724
t2线程11478
t1线程26962
t2线程29358
t1线程24464
t2线程26962
t2线程24464

懒汉模式 

第一次访问实例对象时才创建

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (_ins == nullptr)		//提高效率
		{
			_imtx.lock();
			if (_ins == nullptr)		//线程安全和只new一次
			{
				_ins = new Singleton;
			}
			_imtx.unlock();
		}
		return _ins;
	}

	void Add(const string& str)
	{
		_vmtx.lock();
		_v.push_back(str);
		_vmtx.unlock();
	}

	void Print()
	{
		_vmtx.lock();
		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;
		_vmtx.unlock();
	}
private:
	//限制类外面随意创建对象
	Singleton() 
	{}
private:
	mutex _vmtx;
	vector<string> _v;	//想让vector的数据,在全局只有唯一一份
	static Singleton* _ins;
	static mutex _imtx;
};

Singleton* Singleton::_ins = nullptr;
mutex Singleton::_imtx;

int main()
{
	srand(time(0));

	int n = 10;
	thread t1([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t1线程" + to_string(rand()));	//添加随机数
		}
	});
	thread t2([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t2线程" + to_string(rand()));	//添加随机数
		}
	});

	t1.join();
	t2.join();
	Singleton::GetInstance()->Print();

	return 0;
}
	static Singleton* GetInstance()   //懒汉模式 另一种写法
	{
		//C++11之前,不能保证初始化静态局部对象的线程安全问题(不安全)
		//C++11之后,可以保证初始化静态局部对象的线程安全问题(安全)
		static Singleton inst;
		return &inst;
	}

懒汉和饿汉的优缺点

饿汉:

缺点:

1. 如果单例对象很大,main函数之前就要申请,第一暂时不需要使用却占用资源, 第二程序启动会变慢.

2. 如果两个单例都是饿汉,并相互有依赖关系, 要求单例1先创建, 单例2再创建(例如数据库先启动,缓存后启动), 饿汉无法控制谁先创建的顺序

优点:

比懒汉简单

懒汉优点:解决了饿汉的缺点

懒汉缺点:比饿汉复杂

懒汉有线程安全问题, 饿汉没有线程安全问题

保证单例对象回收
#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include <time.h>
using namespace std;

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (_ins == nullptr)		//提高效率
		{
			_imtx.lock();
			if (_ins == nullptr)		//线程安全和只new一次
			{
				_ins = new Singleton;
			}
			_imtx.unlock();
		}
		return _ins;
	}

	//不需要显式地释放单例对象
	//因为一般全局都要使用单例对象. 所以不需要显式地释放. 程序结束时最后会系统释放
	//有些特殊场景,想显式的释放一下
	static void DelInstance()
	{
		_imtx.lock();
		if (_ins != nullptr)
		{
			delete _ins;
			_ins = nullptr;
		}
		_imtx.unlock();
	}

	//单例对象回收
	class GC		//内部类.写成外部类也可以
	{
	public:
		~GC()
		{
			DelInstance();
		}
	};

	static GC _gc;	//定义静态全局gc对象
	~Singleton()
	{
		//持久化-永久存下来
		// // 要求程序在结束前, 将数据写到文件中.
		//单例对象析构时做持久化.
	}	

	void Add(const string& str)
	{
		_vmtx.lock();
		_v.push_back(str);
		_vmtx.unlock();
	}

	void Print()
	{
		_vmtx.lock();
		for (auto& e : _v)
		{
			cout << e << endl;
		}
		cout << endl;
		_vmtx.unlock();
	}
private:
	//限制类外面随意创建对象
	Singleton() 
	{}
private:
	mutex _vmtx;
	vector<string> _v;	//想让vector的数据,在全局只有唯一一份
	static Singleton* _ins;
	static mutex _imtx;
};

Singleton* Singleton::_ins = nullptr;
mutex Singleton::_imtx;

Singleton::GC Singleton::_gc;
int main()
{
	srand(time(0));

	int n = 10;
	thread t1([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t1线程" + to_string(rand()));	//添加随机数
		}
	});
	thread t2([n]() {
		for (size_t i = 0; i < n; i++)
		{
			Singleton::GetInstance()->Add("t2线程" + to_string(rand()));	//添加随机数
		}
	});

	t1.join();
	t2.join();
	Singleton::GetInstance()->Print();

	return 0;
}

t1线程41
t2线程41
t1线程18467
t2线程18467
t2线程6334
t2线程26500
t2线程19169
t1线程6334
t1线程26500
t1线程19169
t1线程15724
t1线程11478
t1线程29358
t1线程26962
t1线程24464
t2线程15724
t2线程11478
t2线程29358
t2线程26962
t2线程24464

补充:防拷贝
	//无论饿汉,懒汉,都要防拷贝
	Singleton(const Singleton& s) = delete;	//不封拷贝构造无法保证单例
		//Singleton s(*Singleton::GetInstance());
	Singleton& operator=(const Singleton& s) = delete;

类型转换

static_cast

reinterpret_cast

const_cast

dynamic_cast

前三种为了解决c语言使用不规范 ~,第四种是c++相较于c语言新增的。

class A
{
public:
	virtual void f() {}
};

class B : public A
{

};

void fun(A* pa, const string& s)
{
	std::cout << "pa" << s << std::endl;

	B* pb1 = (B*)pa;
	B* pb2 = dynamic_cast<B*>(pa);	//安全的 

	std::cout << "[强制转换]pb1:" << pb1 << endl;
	std::cout << "[dynamic_cast转换]pb2:" << pb2 << endl << endl;
	//检查父类指针,如果原本指向父类对象,就转失败;
	//如果原本指向子类对象,就转成功
}


int main()
{
	//double d = 12.34;
	//int a = static_cast<int>(d);	//相似类型可以转, 整形不可转成指针  隐式类型转换
	//cout << a << endl;

	//int *p = reinterpret_cast<int*>(a);	//重新解释的转换 ,不可用static_cast 强制类型转换

	//const int a = 2;
	//int* p = const_cast<int*>(&a);	//对应c语言的下一行
	//int* p2 = (int*)&a;
	//*p = 3;
	//cout << a << endl;	//2
	//cout << *p << endl;	//3
	//cout << *p2 << endl;
	//加了const后,编译器优化,把a存到寄存器, 从寄存器取a. 
	//
	
	//4 .dynamic_cast 动态转换  只有c++有
	//指针 / 引用可转 , 对象不可转
	

	A a;
	B b;
	//bb = (B)aa;	//对象不可转
	//dynamic转换是安全的, 强制类型转换是不安全的
	fun(&a, "指向父类对象");
	fun(&b, "指向子类对象");

	return 0;
}

pa指向父类对象
[强制转换]pb1:0000009495EFF498
[dynamic_cast转换]pb2:0000000000000000

pa指向子类对象
[强制转换]pb1:0000009495EFF4B8
[dynamic_cast转换]pb2:0000009495EFF4B8
 

RAII  ---- 资源 请求 is 初始化

RTTI ---- Run-time Type identifification的简称,即:运行时类型识别。

C++ 通过以下方式来支持 RTTI
1. typeid 运算符
	cout << typeid(a).name() << endl;	//class A
2. dynamic_cast 运算符
识别指针是指向父类还是子类?
3. decltype
常见面试题
1. C++ 中的 4 中类型转化分别是: _________ _________ _________ _________
2. 说说 4 中类型转化的应用场景。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

雷达检测及MATLAB仿真

文章目录 前言一、雷达检测二、Matlab 仿真1、高斯和瑞利概率密度函数①、MATLAB 源码②、仿真 2、归一化门限相对虚警概率的曲线①、MATLAB 源码②、仿真 3、检测概率相对于单个脉冲 SNR 的关系曲线①、MATLAB 源码②、仿真 4、改善因子和积累损失相对于非相干积累脉冲数的关系…

使用xlwings实现对excel表中指定列隔行求和

需要对上表中的营业额隔行求和&#xff0c;即橙色背景颜色的求和&#xff0c;无背景颜色的求和。 看了大佬的视频&#xff0c;有两种方法&#xff1a; 1.加辅助列 2.使用判断行的奇偶函数&#xff0c;然后在用sumproduct函数 在此&#xff0c;我使用xlwings对excel表中数据…

2023年【北京市安全员-C3证】考试题库及北京市安全员-C3证在线考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-C3证考试题库是安全生产模拟考试一点通总题库中生成的一套北京市安全员-C3证在线考试&#xff0c;安全生产模拟考试一点通上北京市安全员-C3证作业手机同步练习。2023年【北京市安全员-C3证】考试题库及…

vmware开启ipv6

说明 在 ipv4 基础上配置ipv6网络。 分享 大数据博客列表开发记录汇总个人java工具库 项目https://gitee.com/wangzonghui/object-tool 包含json、string、集合、excel、zip压缩、pdf、bytes、http等多种工具&#xff0c;欢迎使用。 vm开启ipv6 设置vmware 打开vmware点击编…

MySQL的索引和复合索引

由于MySQL自动将主键加入到二级索引&#xff08;自行建立的index&#xff09;里&#xff0c;所以当select的是主键或二级索引就会很快&#xff0c;select *就会慢。因为有些列是没在索引里的 假设CA有1kw人咋整&#xff0c;那我这个索引只起了前一半作用。 所以用复合索引&am…

gorm使用之各种表关系实例-主外键->struct

gorm使用之各种表关系实例-主外键->struct 一对多关系(用户与文章) 如: 老板与员工 女神和舔狗 老师和学生 班级与学生 用户与文章 ...以用户与文章举例 models应当如,注意&#xff01;&#xff01;&#xff1a;User表中的ID应当与Article中的UID一直&#xff0c;大小和…

Java面向对象(进阶)-- 面向对象特征之三:多态性

文章目录 一、多态的形式和体现&#xff08;1&#xff09;为什么需要多态性(polymorphism)&#xff1f;&#xff08;2&#xff09; 对象的多态性 二、 多态的理解&#xff08;1&#xff09;如何理解多态性&#xff08;2&#xff09;Java中多态性的体现&#xff08;3&#xff09…

VS c++多文件编译

前言&#xff1a;记录下我这个菜鸡学习的过程&#xff0c;如有错误恳请指出&#xff0c;不胜感激&#xff01; 1.简单多文件编译调试 文件目录&#xff1a; 编译&#xff1a; -g选项是告诉编译器生成调试信息&#xff0c;这样可以在程序崩溃或出现错误时更容易地进行调试。这…

减轻关键基础设施网络安全风险的 3 种方法

物理安全和网络安全之间存在相当大的重叠&#xff0c;特别是在保护关键基础设施方面。防止基础设施被篡改需要在物理安全方面进行大量投资&#xff0c;但任何连接到互联网的设备都代表着更广泛网络的潜在攻击点。 缺乏足够保护的设备可能会给这些对手在网络中提供立足点&#…

张小泉的“老字号”快守不住了:限期整改,业绩和产品各有危机

撰稿|行星 来源|贝多财经 11月8日&#xff0c;商务部等5部门发布了中华老字号的复核结果。结果显示&#xff0c;全国有981家中华老字号企业通过了复核&#xff0c;73家中华老字号企业附条件通过复核&#xff0c;另有55家企业未能通过复核。 贝多财经发现&#xff0c;张小泉股…

【Python 千题 —— 基础篇】账号登录

题目描述 题目描述 简易登录系统。你的账号密码分别是 “student”&#xff0c;“123456”&#xff1b;请使用 if-else 设计一个简易登录系统&#xff0c;输入账号密码。登陆成功输出 “Welcome !”&#xff0c;登录失败输出 “Login failed !” 输入描述 输入账号和密码。…

Python环境安装、Pycharm开发工具安装(IDE)

Python下载 Python官网 Python安装 Python安装成功 Pycharm集成开发工具下载&#xff08;IDE&#xff09; PC集成开发工具 Pycharm集成开发工具安装&#xff08;IDE&#xff09; 安装完成 添加环境变量&#xff08;前面勾选了Path不用配置&#xff09; &#xff08;1&…

电脑出现病毒提示解决办法

已检测:Trojan:Win32/WacatacA!ml 状态:已隔离 隔离的文件在不会损害设备的受限区域内。系统将自动删除它们 日期:2023/11/1013:21详细信息这个程序很危险&#xff0c;而且执行来自攻击者的命令 受影响的项目: driver: haStdnetfilter file: C:WINDOWSsystem32\drivers\haStdne…

keil和proteus联动要点

一、keil与proteus如何进行联动&#xff1f; 1.先安装vdmagdi.exe&#xff0c;这是驱动 2.要保证keil工程编译通过&#xff0c;左上角红色图标进行编译&#xff0c;黑色框图标进行链接。 3.生成hex文件 先点击这个图标 按照顺序点击&#xff0c;生成HEX文件。 4.在打开的prot…

思维模型 多看效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。越熟悉&#xff0c;越喜欢。 1 多看效应的应用 1.1 多看效应在广告和营销领域的应用 1 可口可乐之歌 可口可乐公司在 20 世纪 60 年代推出了“可口可乐之歌”广告&#xff0c;这个广告通…

守护进程daemon(),C 库函数asctime、localtime,UDEV的配置文件,开机自启动,自动挂载U盘

一、守护进程 二、daemon()函数 三、C 库函数asctime、localtime 四、设置守护进程开机自启动 五、守护进程应用 编写判断守护进程是否在运行的程序 守护进程不让控制程序退出 把相关守护进程设置成开机自启动 六、dmesg 七、UDEV的配置文件&#xff08;udev的rules编写&am…

jupyter notebook中markdown改变图像大小

文章目录 &#x1f56e;原始图像&#x1f56e;改变图像大小&#x1f56e;使图像靠左 在 jupyter notebook中&#xff0c;导入的图片过大&#xff0c;想要改变图像的大小 &#x1f56e;原始图像 &#x1f56e;改变图像大小 复制小括号里面的内容到src后面&#xff0c;满足<…

软件测试现状以及行业分析

大家都知道最近 ChatGPT 爆火&#xff0c;国外巨头争相宣布自己的相关计划&#xff0c;国内有点实力的企业也在亦步亦趋地跟进。不出意料的是&#xff0c;关于测试职业要被淘汰的话题又&#xff08;为什么要说又&#xff1f;&#xff09;在扎堆出现&#xff0c;内容跟之前还是大…

Leetcode—9.回文数【简单】

2023每日刷题&#xff08;二十六&#xff09; Leetcode—9.回文数 直接法实现代码 bool isPalindrome(int x) {int len 0;int arr[10] {0};int i 0;if(x < 0) {return false;}while(x) {arr[i] x % 10;x / 10;len; }for(i 0; i < len / 2; i) {if(arr[i] ! arr[le…

【LLM_03】自然语言处理基础_1

一、自然语言处理基基本任务和应用1、自然语言处理的基本任务2、搜索引擎的基本工作原理3、知识图谱的构建4、应用 二、词表示与语言模型1、词表示2、上下文3、语言模型4、神经网络在语言模型的应用 三、神经网络1、神经网络基本组成元素2、如何训练神经网络3、计算图的概念4、…