C++知识点 -- 特殊类设计

news2024/9/22 7:26:45

C++知识点 – 特殊类设计

文章目录

  • C++知识点 -- 特殊类设计
  • 一、不能被拷贝的类
  • 二、 只能在堆上创建对象的类
  • 三、 只能在栈上创建对象的类
  • 四、 不能被继承的类
  • 五、 只能创建一个对象的类(单例模式)
    • 1.饿汉模式
    • 2.懒汉模式
    • 3. 单例对象释放问题:


一、不能被拷贝的类

不让编译器默认生成拷贝构造和赋值重载,c++11可以在默认成员函数后加上 = delete,表示让编译器删除该默认成员函数;

class CopyBan
{
public:
	CopyBan(const CopyBan& cb) = delete;
	CopyBan& operator=(const CopyBan& cb) = delete;

private:

	int _a;
};

二、 只能在堆上创建对象的类

在这里插入图片描述
对于普通类,在栈、堆和静态区都能够创建对象;
要设计只能在堆上创建对象的类,就需要堆构造函数或者析构函数做出一定调整;

方法一
析构函数设为私有,这样在栈和静态区的对象就无法调用析构函数销毁对象,只有在对上创建的对象调用delete才能够销毁对象,可以写一个公有函数来delete对象,完成对象的销毁;

class HeapOnly
{
public:
	//公有函数调用delete销毁对象,设置成静态成员,使用类域就能够调用
	static void Delete(HeapOnly* p)
	{
		delete p;
	}

private:
	//析构函数私有化
	~HeapOnly()
	{}

	int _a;
};

在这里插入图片描述
可以看出,栈和静态区都无法创建StackOnly对象,只有通过new才能在堆上创建对象;

方法二
构造函数私有化,这样在哪里都无法创建对象了,再添加一个公有的静态成员函数,完成函数内部在堆上创建对象,同时将拷贝构造和赋值重载也设为私有,否则还能通过拷贝的方式在其他地方创建对象;

class HeapOnly
{
public:
	//提供一个公有的,在堆上创建对象的方式
	static HeapOnly* CreatObj()
	{
		HeapOnly* pho = new HeapOnly;
		return pho;
	}

private:

	//构造函数私有化
	HeapOnly()
	{}
	//拷贝构造和赋值重载也删除
	HeapOnly(const HeapOnly& so) = delete;
	HeapOnly& operator=(const HeapOnly& so) = delete;

	int _a;
};

在这里插入图片描述
效果一样;

三、 只能在栈上创建对象的类

构造函数私有化,提供一个公有的静态成员函数,函数内部调用构造函数在堆上创建对象,返回该对象

但是这种方式并不能阻止拷贝构造在其他地方创建对象,简单地将拷贝构造和赋值重载delete,会导致CreateObj这个函数传值返回出问题,因为传值返回需要调用拷贝构造,我们可以通过delete掉operator new来限制new创建对象

class StackOnly
{
public:
	static StackOnly CreateObj()
	{
		StackOnly so;
		return so;
	}

private:
	StackOnly()
		: _a(0)
	{}

	void* operator new(size_t n) = delete;

	int _a;
};

在这里插入图片描述
这种方法并不能防止在静态区创建对象;

四、 不能被继承的类

在c++11中,用final修饰一个类,表示该类不能被继承;

//该类无法被继承
class A final
{

};

五、 只能创建一个对象的类(单例模式)

一个类只能创建一个对象,就是单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享;
单例模式有两种实现:

1.饿汉模式

程序启动时就创建一个唯一实例对象;
(1)构造函数私有化,就不能通过其他方式初始化了;
(2)私有成员中声明一个静态的指向该对象的指针,静态成员属于这个类;
(3)在类外使用new初始化这个静态指针;
(4)提供公有函数来返回这个指向对象的静态指针;

class Singleton
{
public:
	static Singleton* GetInstace()
	{
		return _pinst;
	}

	void* Alloc(size_t n)
	{
		void* ptr = nullptr;
		//...
		return ptr;
	}

	void Delloc(void* ptr)
	{
		//...
	}

private:
	//构造函数私有化
	Singleton()
	{}

	char* _ptr = nullptr;
	static Singleton* _pinst;//声明
};

//定义
Singleton* Singleton::_pinst = new Singleton;

//使用
void test()
{
	void* ptr1 = Singleton::GetInstace()->Alloc(10);
	Singleton::GetInstace()->Delloc(ptr1);

}

优点:简单、没有线程安全问题
缺点:
(1)一个程序中,多个单例,并且有先后创建初始化顺序要求时,饿汉无法控制。
比如程序两个单例类A 和 B,假设要求A先创建初始化,B再创建初始化。
(2)饿汉单例类,初始化时任务多,会影响程序启动速度。

2.懒汉模式

第一次使用对象时才创建实例对象;
(1)构造函数私有化,私有静态对象指针;
(2)公有静态成员函数,只有在对象指针为空的时候才创建对象,返回指向对象的指针;
(3)需要释放资源的场景,可以内嵌一个垃圾回收类;
实例化出一个静态垃圾回收对象,出了对象作用域(main函数结束后)就会调用析构,在析构里面将单例对象的资源全部释放;

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (_pinst == nullptr)
		{
			_pinst = new Singleton;
		}

		return _pinst;
	}

	void* Alloc(size_t n)
	{
		void* ptr = nullptr;
		//...
		return ptr;
	}

	void Delloc(void* ptr)
	{
		//...
	}

	//内嵌垃圾回收类
	class CGarbo
	{
	public:
		~CGarbo()
		{
			if (_pinst)
			{
				delete _pinst;
			}
		}
	};

private:
	//构造函数私有化
	Singleton()
	{}

	char* _ptr = nullptr;
	static Singleton* _pinst;//声明
};

//定义
Singleton* Singleton::_pinst = nullptr;

//回收对象:main函数结束后,会调用析构函数,就会释放单例对象
static Singleton::CGarbo gc;


void test()
{
	void* ptr1 = Singleton::GetInstance()->Alloc(10);
	Singleton::GetInstance()->Delloc(ptr1);
}

优点:
(1)控制顺序
(2)不影响启动速度
缺点:
(1)相对复杂
(2)线程安全问题要处理好

3. 单例对象释放问题:

(1)一般情况下,单例对象不需要释放的。因为一般整个程序运行期间都可能会用它。
单例对象在进程正常结束后,也会资源释放。
(2)有些特殊场景需要释放,比如单例对象析构时,要进行一些持久化(往文件、数据库写)操作。

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

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

相关文章

【Python入门篇】——Python中判断语句(布尔类型,比较运算符,if语句)

作者简介: 辭七七,目前大一,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: Python入门,本专栏主要内容为Python的基础语法,Python中的选择循环语句…

Verilog 编程——奇偶分频(50%占空)

引言 最近准备一些笔试面试,想再把时钟奇偶分频的再整理一下。 我之前写过一个PWM产生的模块,里面有任意频率/占空比的时钟生成。可以参考: 基于FPGA的PWM发生器设计https://blog.csdn.net/qq_43045275/article/details/128365705?ops_re…

Scala学习(一)

1.什么是Scala Scala将面向对象和函数式编程结合成一种简洁的高级语言。Scala的静态类型有助于避免复杂应用程序中的错误。 1.1 为什么要学习Scala? Spark基于内存的大数据计算框架,而Spark就是Scala开发的。所以为了学习好Spark需要掌握Scala语言。 …

learn C++ NO.3 ——类和对象(1)

1.初步理解面向过程和面向对象 C语言是面向过程的高级编程语言,而C是面向对象的高级编程语言。那么两者有什么区别呢?且看下图分析。 面向过程语言就是逐步拆分并解决问题。其特点是过程化和模块化,数据和对数据的操作是分离的。 由于面向过…

《LeetCode》—— 哈希

今天刷题讲解的主要讲的是关于——哈希这个知识点的题目讲解。 目录 (一)缺失的第一个正整数 (二)数组中只出现一次的两个数字 1、直接法 2、哈希 (三)直线上最多的点数 (一)缺…

力扣题库刷题笔记735-行星碰撞

1、题目如下: 2、个人Python代码实现 个人代码思路,主要是新建一个列表stack,将原列表asteroids中的元素依次加入到stack中。以上代码可能会有两部分比较冗余的部分,一是两个标志位可以不用单独声明,二是当stack列表中…

解析内存中的高性能图结构

在进行各种图处理、图计算、图查询的时候,内存或是硬盘中如何存储图结构是一个影响性能的关键因素。本文主要分析了几种常见的内存图结构,及其时间、空间复杂度,希望对你有所启发。 通常来说,对于图结构的几种常见的基础操作&…

通过SSH隧道安全消费Kafka数据

一.背景 由于我们有个业务在阿里云部署了Kafka,但是想直接在本地IDC机房服务器直接通过公网消费Kafka进行业务处理。这个本来也不是什么难事,阿里云把9092默认端口打开运行访问即可,也不不值得再写这篇博客了。 这个事情让人特别关注的一个主…

【记录】ChatGPT|图片预览魔法咒语魔改,使用 ChatGPT 返回大量可以跳转的链接

很早的时候,我已经留意到 ChatGPT 会以返回图片的 markdown 格式来显示图片,很可能拥有一定的图片上传功能,但是它往往会显示得有些问题。一些代码图片之类的或者风景图什么的都不是很会。 但其实 ChatGPT 是可以直接返回图片类型的回复的&a…

C++初始化列表

1.初始化列表概述 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。 2.为什么使用初始化列表 在创建对象时,编译器通过调用构造函数&#xff0c…

个人电脑操作系统

UEFI(Unified Extensible Firmware Interface,全称统一的可扩展固件接口)是一种个人电脑系统规格,用来定义操作系统与系统固件之间的软件界面,作为BIOS的替代方案。其前身是Intel在1998年开始开发的Intel Boot Initiat…

【static_cast、reinterpret_cast、const_cast、dynamic_cast】C++类型转换

C类型转换 引入C语言中的类型转换 C的强制类型转换static_castreinterpret_catconst_castdynamic_cast向下转型的安全问题 explicit4种类型转换的应用场景 RTTI 引入 C语言中的类型转换 C语言和C都是强类型语言,如果赋值运算符左右两侧变量的类型不同,…

ChatGPT一键私有部署,全网可用,让访问、问答不再受限,且安全稳定!

前言 ChatGPT由于在访问上有一些限制,使用并不便利。目前国内可以直接访问的大部分是调用API返回结果,我们去使用时总会有次数限制,而且它们可能随便崩掉。 其实,目前我们访问过的大部分国内的网页包括UI,其实是套用了…

过滤器对前端请求参数进行解码URLDecoder,接口接收参数类型为map,解码无效问题

文章目录 一、前言二、设计思路三、代码实现四、启动测试五、过滤器解码无效六、源码跟踪七、解决方案八、再次重启测试九、总结 一、前言 最近做的一个公司项目,因为客户需要对特殊字符做搜索,但是前端的请求参数无法传递到后端,所以前端对…

VS2017中Qt项目数据库连接——包含报错比如QMYSQL driver not loaded(细心看到最后,一定能解决你想解决的问题)

我把爆的错误QMYSQL driver not loaded写在文章末尾了,大家看一看!前面是配置数据库 一、测试 VS2017 中 Qt 项目数据库连接 打开 VS2017,文件——新建项目,右侧输入框输入 Qt 确定后点击下一步,勾选模块 基类也是默…

RSU路测单元,你知道多少?

一、什么是RSU路测单元? RSU路测单元是实现智慧的路、车路协同的关键设备,设置在路侧,与附近过往车辆进行双向通信、交互数据,是智能交通系统中的一种重要设备。RSU可以连接路面原有电子设备,比如信号灯和摄像头&…

一文解决Xshell无法连接vmware上的centos

问题描述 win10系统上安装VMware workstation16 pro,装好后安装centos虚拟机,在设置network & hostname时选择的NAT模式,即使用自定义的网关和IPv4地址,最后配置完成后centos主机地址信息如下,在虚拟机内部进行pi…

【一览无余】Vue框架下Cesium加载遥感地图使用GeoServer切割TIF大文件对外发布WMS服务进行地图绘制(科普篇2/2)

【一览无余】Vue框架下Cesium加载遥感地图使用GeoServer切割TIF大文件对外发布WMS服务进行地图绘制(科普篇2/2) 二、Cesium是弄啥嘞2.1 WebGL2.1.1 WebGL是什么2.1.2 WebGL优点 2.2 Cesium是什么2.3 Cesium能干什么2.4 Cesium相关工具有哪些2.5 相关案例…

Echarts 3D散点图

文章目录 以下是一个 html echarts的案例 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>ECharts 3D Scatter Plot Demo</title><!-- 引入 ECharts --><script src"https://cdnjs.cloudflare.com/…

急吗?光急可没用呀!满满干货,两小时速成,别搁那干瞪眼了!

全球产业链加速重构&#xff0c;各种不确定性加大&#xff01;数字经济规模不断提升&#xff0c;为企业转型与发展创造大量机会&#xff01;企业亟须以数字化为工具或手段&#xff0c;再造组织流程和业务流程&#xff0c;以数字化确定性应对外部环境变化的不确定性&#xff0c;…