C++_特殊类的设计和单例模式

news2025/1/18 21:09:31

文章目录

  • 学习目标:
    • 1.请设计一个类,不能被拷贝
    • 2. 请设计一个类,只能在堆上创建对象
    • 3. 请设计一个类,只能在栈上创建对象
    • 4. 请设计一个类,不能被继承
    • 5. 请设计一个类,只能创建一个对象(单例模式)
  • 特殊类的设计
    • 1. 防拷贝类的设计
    • 2.仅堆上创建类的设计
    • 3.仅栈上创建类的设计
    • 4. 不可被继承类的设计
      • C++98
      • C++11
    • 5.单例模式的设计
    • 饿汉模式
    • 懒汉模式
    • C++11之后的懒汉模式

学习目标:

1.请设计一个类,不能被拷贝

拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。

2. 请设计一个类,只能在堆上创建对象

实现方式:

  1. 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
  2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。

3. 请设计一个类,只能在栈上创建对象

同上将构造函数私有化,然后设计静态方法创建对象返回即可。

4. 请设计一个类,不能被继承

  1. C++98 中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
  2. C++11方法 final关键字,final修饰类,表示该类不能被继承。

5. 请设计一个类,只能创建一个对象(单例模式)


特殊类的设计

1. 防拷贝类的设计

拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。

//防拷贝类的设计
class BanCopy {
public:
	BanCopy(int value)
		:_value(value){}
private:
	BanCopy(const BanCopy& bc) = delete;
	BanCopy& operator= (const BanCopy& bc) = delete;
	int _value;
};
int main()
{
	BanCopy bc1(1);
	BanCopy bc2(bc1);
	return 0;
}

在这里插入图片描述

2.仅堆上创建类的设计

思路则是私有化构造函数防止随意创建对象,仅通过调用类中的静态函数来获取堆上创建的实例。

//仅堆上创建类的设计
class HeapOnly {
public:
	static HeapOnly* CreateInstance(int value)
	{
		return new HeapOnly(value);
	}
private:
	HeapOnly(int value)
		:_value(value){}

	//也要限制一下拷贝构造,因为可以通过拷贝构造来在栈上创建对象
	HeapOnly(const HeapOnly& ho) = delete;
	int _value;
};

int main()
{
	HeapOnly ho1(1);
	HeapOnly* ho2 = HeapOnly::CreateInstance(1);
	HeapOnly ho3 = *ho2;
}

在这里插入图片描述


3.仅栈上创建类的设计

与仅堆上创建类的设计相似,通过私有化构造函数防止随意创建对象。

//仅栈上创建类的设计
class StackOnly {
public:
	static StackOnly CreateInstance(int value)
	{
		return StackOnly(value);
	}
private:
	StackOnly(int value)
		:_value(value){}

	//禁用new调用拷贝构造
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;

	int _value;
};

int main()
{
	StackOnly so1(2);
	StackOnly so2 = StackOnly::CreateInstance(2);
	StackOnly* so3 = new StackOnly(3);
	StackOnly* so4 = new StackOnly(so2);
	//需要注意的是,虽然说我们可以防止在堆上创建对象,但是我们却无法阻止在静态区创建对象
	static StackOnly so5 = StackOnly::CreateInstance(3);
	return 0;
}

4. 不可被继承类的设计

C++98

class NoneInherit {

private:
	NoneInherit(int value)
		:_value(value){}

	int _value;
};

class Child : public NoneInherit {
public:
	Child(int value, int data)
		:NoneInherit(value)
		,_data(data){}

private:
	int _data;
};

在这里插入图片描述

C++11

使用final关键字

class NoneInherit final{
public:
	NoneInherit(int value)
		:_value(value){}

private:
	int _value;
};

class Child : public NoneInherit {
public:
	Child(int value, int data)
		:NoneInherit(value)
		,_data(data){}

private:
	int _data;
};

在这里插入图片描述

5.单例模式的设计

饿汉模式

饿汉模式意思是 当程序刚开始启动时,就自动创建对象。 因为这里我们采用了静态类成员的思路。

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

private:
	Singleton(int value = 0)
		:_value(value) {}

	Singleton(Singleton const&) = delete;

	Singleton& operator=(Singleton const&) = delete;

	int _value;

	static Singleton only_instance;
};

Singleton Singleton::only_instance;

int main()
{
	Singleton* s = Singleton::GetInstance();
}

懒汉模式

懒汉模式区别于饿汉模式就是饿汉是程序一起的就创建的单例对象,但是懒汉则是程序运行一段时间后,需要创建再创建单例对象。

//懒汉模式
#include<thread>
#include<mutex>
class Singleton {
public:
	static Singleton* GetInstance()
	{
		if (only_instance == nullptr)
		{
			p_mutex.lock();
			if (only_instance == nullptr)
			{
				only_instance = new Singleton();
			}
			p_mutex.unlock();
		}
		return only_instance;
	}

private:
	Singleton(int value = 0)
		:_value(value) {}

	Singleton(Singleton const&) = delete;

	Singleton& operator=(Singleton const&) = delete;

	int _value;

	//保护线程安全 加上互斥锁
	static std::mutex p_mutex;
	static Singleton* only_instance;
};
Singleton* Singleton::only_instance = nullptr;

这里提出一个疑问,像懒汉这种写法方式,我们的唯一实例new出来的,析构需不需要写一个delete来释放资源?
其实可以不用写,因为是唯一实例,除非说特殊需求需要中途释放或者说确定了之后不再使用该对象就可以自己写一套destroy函数,这并没有什么难度。

我们可以试着写一个自动回收

#include<thread>
#include<mutex>
class Singleton {
public:
	static Singleton* GetInstance()
	{
		if (only_instance == nullptr)
		{
			p_mutex.lock();
			if (only_instance == nullptr)
			{
				only_instance = new Singleton();
			}
			p_mutex.unlock();
		}
		return only_instance;
	}
	class CGarbo {
	public:
		~CGarbo(){ 
			if (only_instance)
			{
				std::cout << only_instance->_value << std::endl;
				delete only_instance;
			}
		}
	};
private:
	Singleton(int value = 0)
		:_value(value) {}

	Singleton(Singleton const&) = delete;

	Singleton& operator=(Singleton const&) = delete;

	int _value;

	//保护线程安全 加上互斥锁
	static std::mutex p_mutex;
	static Singleton* only_instance;
	static CGarbo cg;
};

std::mutex Singleton::p_mutex;
Singleton::CGarbo Singleton::cg;
Singleton* Singleton::only_instance = nullptr;

int main()
{
	Singleton* s1 = Singleton::GetInstance();
	return 0;
}

在这里插入图片描述

C++11之后的懒汉模式

#include<thread>
#include<mutex>
class Singleton {
public:
	static Singleton* GetInstance()
	{
		//C++11之后路这种写法是线程安全的
		static Singleton only_instance;
		return &only_instance;
	}

private:
	Singleton(int value = 0)
		:_value(value) {}

	Singleton(Singleton const&) = delete;

	Singleton& operator=(Singleton const&) = delete;

	int _value;
	static std::mutex p_mutex;

};
std::mutex Singleton::p_mutex;

int main()
{
	Singleton* s1 = Singleton::GetInstance();
	return 0;
}

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

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

相关文章

Django中的数据库优化与ORM性能调优【第169篇—ORM性能调优】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Django中的数据库优化与ORM性能调优 在开发基于Django的Web应用程序时&#xff0c;数据库是…

上下文输入无限制,谷歌发布Infini-Transformer

去年&#xff0c;百川智能发布号称全球最长的上下文窗口大模型Baichuan2-192K&#xff0c;一次性可输入35万字&#xff0c;超越GPT-4。 今年3月&#xff0c;Kimi智能助手宣布在上下文窗口技术上突破200万字。 紧追其后&#xff0c;国内各大互联网巨头纷纷布局升级自家大模型产…

【C语言】贪吃蛇项目(1) - 部分Win32 API详解 及 贪吃蛇项目思路

文章目录 一、贪吃蛇项目需要实现的基本功能二、Win32 API介绍2.1 控制台2.2 部分控制台命令及调用函数mode 和 title 命令COORD 命令GetStdHandle&#xff08;获取数据&#xff09;GetConsoleCursorInfo&#xff08;获取光标数据&#xff09;SetConsoleCursorInfo &#xff08…

数字化转型之路-云原生与ChaosMeta

作者&#xff1a;刘凇杉&#xff08;chaosmeta-platform发起人&#xff09; 一.引言 随着科技的快速发展和信息时代的到来&#xff0c;数字化转型已成为企业不可或缺的战略选择。作为中国领先的科技金融企业&#xff0c;蚂蚁集团深谙数字化转型的重要性&#xff0c;并在其转型…

LeetCode 704.二分查找

LeetCode 704.二分查找 1、题目 题目链接&#xff1a;704. 二分查找 2、思路 这道题目是要在有序数组 nums 中找到目标值 target&#xff0c;符合二分查找的前提条件&#xff08;线性表必须是有序的&#xff0c;且采用顺序存储&#xff09;。同时题目还强调数组中无重复元…

2024最新在线工具箱网站系统源码

(购买本专栏可免费下载栏目内所有资源不受限制,持续发布中,需要注意的是,本专栏为批量下载专用,并无法保证某款源码或者插件绝对可用,介意不要购买!购买本专栏住如有什么源码需要,可向博主私信,第二天即可发布!博主有几万资源) 2024最新在线工具箱网站系统源码是一…

怎样将excel的科学计数法设置为指数形式?

对了&#xff0c;这个问题中所谓的“指数形式”是指数学上书写的右上标的指数格式&#xff0c;能不能通过单元格设置来做这个格式的转换呢&#xff1f; 一、几个尝试 以下&#xff0c;以数字123000为例来说明。 情况1.转换成数学上的书写方式&#xff0c;如下图的样子&#x…

基于SpringBoot+Vue的二手车交易系统的设计与实现(源码+文档+包运行)

一.系统概述 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统二手车交易信息管理难度大&#xff0c;容错率低&…

Java面试八股之fail-fast和fail-safe的区别

简述fail-fast和fail-safe的区别 定义与基本概念 fail-fast&#xff1a; 定义&#xff1a;fail-fast是一种迭代器机制&#xff0c;当集合在迭代过程中被结构上修改&#xff08;如添加、删除元素&#xff09;&#xff0c;会立即抛出ConcurrentModificationException异常&…

离岸人民币与人民币国际化

参考 什么是离岸人民币&#xff1f;它有什么用&#xff1f; - 知乎 “人民币就是人民币&#xff0c;为什么要在它前面加上离岸二字&#xff1f;” “既然有离岸人民币&#xff0c;是否有在岸人民币&#xff1f;” 今天我们就简单了解一下什么是离岸人民币。 离岸/在岸人民币…

朗致集团面试-Java架构师

总结 三轮面试&#xff0c;第一轮是逻辑测试性格测试&#xff0c;第二轮是技术面试&#xff08;面试官-刘老师&#xff09;&#xff0c;第三轮是CTO面试&#xff08;面试官-屠老师&#xff09;。如果第三轮面试通过&#xff0c;考官会问你薪资意向&#xff0c;如果满意的话HR就…

5. Mysql的binlog介绍

参考&#xff1a;InnoDB学习&#xff08;三&#xff09;之BinLog 1. BinLog介绍 BinLog又称为二进制日志&#xff0c;是MySQL服务层的数据日志&#xff0c;MySQL所有的存储引擎都支持BinLog。 BinLog记录了MySQL中的数据更新和可能导致数据更新的事件&#xff0c;可以用于主从…

2024阿里云4核8G服务器租用优惠价格700元一年

阿里云4核8G服务器租用优惠价格700元1年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云优惠 aliyunfuwuqi…

必应Bing国内广告推广,帮助企业降低获客成本!

搜索引擎广告作为数字营销的重要手段之一&#xff0c;因其精准定位和效果可衡量而备受青睐。而在众多搜索引擎平台中&#xff0c;必应Bing以其独特的市场定位和用户群体成为不可忽视的广告推广渠道。云衔科技作为一家专业的数字营销服务提供商&#xff0c;致力于帮助企业实现高…

代码随想录-算法训练营day15【二叉树02:层序遍历、翻转二叉树、对称二叉树】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第六章 二叉树 part02今日内容&#xff1a; ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树 2 详细布置 层序遍历 看完本篇可以一口气刷十道题&#xff0c;试一试&#xff0c; 层序遍历并不难&#xff0c;大…

组织机构代码是哪几位?营业执照怎么看组织机构代码?

组织机构代码是哪几位? 组织机构代码通常指的是组织机构代码证上的一组特定数字&#xff0c;它用于唯一标识一个组织或机构。在中国&#xff0c;组织机构代码由9位数字组成&#xff0c;前8位是本体代码&#xff0c;最后1位是校验码。这组代码是按照国家有关标准编制的&#x…

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo 目录 说明 效果 模型信息 项目 代码 下载 说明 模型下载地址&#xff1a;https://huggingface.co/deepghs/ml-danbooru-onnx 效果 模型信息 OVVersion { BuildNumber 2023.1.0-12185-9e6b00e51cd-releases/20…

kibana源码编译

一、安装nodejs16.14.2及yarn &#xff08;一&#xff09;nodejs 1、下载 https://cdn.npmmirror.com/binaries/node/v16.14.2/node-v16.14.2-linux-x64.tar.gz2、解压 tar -zxf node-v16.14.2-linux-x64.tar.gz -C /app cd /app mv node-v16.14.2-linux-x64 node3、配置环…

redmibook 14 2020 安装 ubuntu

1. 参考博客 # Ubuntu20.10系统安装 -- 小米redmibook pro14 https://zhuanlan.zhihu.com/p/616543561# ubuntu18.04 wifi 问题 https://blog.csdn.net/u012748494/article/details/105421656/# 笔记本电脑安装了Ubuntu系统设置关盖/合盖不挂起/不睡眠 https://blog.csdn.net/…

运动想象 (MI) 分类学习系列 (7) :CMO-CNN

运动想象分类学习系列:CMO-CNN 0. 引言1. 主要贡献2. 提出的算法3. 数据增强策略4. 结果4.1 学科内分类4.2 跨学科分类4.3 数据增强策略4.4 网络可视化4.4.1 短连接可视化4.4.2 滤波器可视化4.4.3 中间特征的可视化 5. 总结欢迎来稿 论文地址&#xff1a;https://www.sciencedi…