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

文章目录

  • 学习目标:
    • 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.mzph.cn/diannao/1235.shtml

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

相关文章

如何在原生项目中集成flutter

两个前提条件&#xff1a; 从flutter v1.17版本开始&#xff0c;flutter module仅支持AndroidX的应用在release模式下flutter仅支持一下架构&#xff1a;x84_64、armeabi-v7a、arm6f4-v8a,不支持mips和x86;所以引入flutter前需要在app/build.gradle下配置flutter支持的架构 a…

《设计模式之美》- 总结

《设计模式之美》- 总结 第一章 概述 1.1 为什么学习代码设计 编写高质量的代码应对复杂代码的开发程序员的基本功职业发展的必备技能 1.2 如何评价代码的质量 1.2.1 可维护性 可维护性代码的特性&#xff1a;代码简洁、可读性好、可扩展性好代码分层结构清晰、模块化程度…

maven问题汇总

​ 1、报错 failed to transfer from http://0.0.0.0/ during a previous attempt. com.byd.xxx:xxx-parent:pom:1.1.0-SNAPSHOT failed to transfer from http://0.0.0.0/ during a previous attempt. This failure was cached in the local repository and resolution is no…

【Pytorch】PytorchCPU版或GPU报错异常处理(10X~4090D)

Pytorch为CPU版或GPU使用报错异常处理 文章目录 Pytorch为CPU版或GPU使用报错异常处理0.检查阶段1. 在conda虚拟环境中安装了torch2.卸载cpuonly3.从tsinghua清华源安装不完善误为cpu版本4.用tsinghua清华源安装成cpu错误版本5.conda中torch/vision/cudatoolkit版本与本机cuda版…

LeetCode - 283.移动零

题目链接&#xff1a; LeetCode - 283.移动零 题目分析&#xff1a; ​​​​​ 题解代码&#xff1a; #include<iostream> #include<vector> using namespace std;class Solution { public:void moveZeroes(vector<int>& nums) {for (int cur 0, des…

【GitBlit】Windows搭建Git服务器详细教程

前言 如果公司或个人想在 Windows 环境下搭建私有的 Git 服务器&#xff0c;那么这个开源的 GitBlit 是一个不错的选择。 Gitblit 是一个开源纯 Java 的用于管理、查看和服务 Git 存储库。它是一个小型的托管集中式存储库工具。支持 SSH、HTTP 和 GIT 协议&#xff0c;开箱即…

Java+springboot开发的医院智能导诊服务系统源码 自动兼容小程序与H5版本

智能导诊系统 一、什么是智慧导诊系统&#xff1f; 智慧导诊系统是一种医院使用的引导患者自助就诊挂号、精准推荐科室、引导患者挂号就诊的系统。该系统结合医院挂号及就诊的HIS系统&#xff0c;为患者带来全流程的信息指引提醒&#xff0c;可以在全院区构建一个精细化、移动…

IP-guard getdatarecord 存在任意文件读取

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 一、产品介绍 IP-guard是由溢信科技股份有限公司开发的一款终端安全管…

x-cmd ai | x openai - 用于发送 openai API 请求,以及与 ChatGPT 对话

介绍 Openai 模块是 Openai 大模型 Chatgpt 3 和 ChatGPT 4 命令行实现。x-cmd 提供了多个不同平台间多种 AI 大模型的调用能力。无论是本地模型还是 Web 服务上的模型&#xff0c;用户都可以在不同的 AI 大模型间直接无缝切换&#xff0c;并能把之前的聊天记录发送给新的大模…

CSS3 伪元素与伪类选择器区别、详解与应用实例

伪元素与伪类两者都是通过在选择器后附加一个特定的关键字来定义&#xff0c;遵循相似的语法规则&#xff0c;并在 CSS 规则块中设置相应的样式。伪元素 能够通过 content 属性添加或替换内容。例如&#xff0c;:before 和 :after 可以插入文本、图像或其他生成的内容。伪类 仅…

Tomcat核心组件深度解析

Server组件 Service组件 连接器Connector组件 容器Container组件

【研发管理】产品经理知识体系-产品创新管理

导读&#xff1a; 产品创新管理对企业的发展具有深远的影响&#xff0c;它不仅是企业保持竞争优势的关键&#xff0c;也是推动企业持续稳定发展的重要动力。因此&#xff0c;企业应高度重视产品创新管理&#xff0c;并采取有效的策略和方法来推动产品创新活动的开展。对于产品经…

第20天:信息打点-红蓝队自动化项目资产侦察企查产权武器库部署网络空间

第二十天 一、工具项目-红蓝队&自动化部署 自动化-武器库部署-F8x 项目地址&#xff1a;https://github.com/ffffffff0x/f8x 介绍&#xff1a;一款红/蓝队环境自动化部署工具,支持多种场景,渗透,开发,代理环境,服务可选项等.下载&#xff1a;wget -O f8x https://f8x.io…

MINIO安装的方法(WindowsLiunx)

2 minio安装教程 注&#xff1a;官方中文文档&#xff1a;MinIO对象存储 Windows — MinIO中文文档 | MinIO Windows中文文档 Liunx 安装方&#xff1a;MinIO对象存储 Linux — MinIO中文文档 | MinIO Linux中文文档 2.1 下载地址 https://dl.min.io/server/minio/…

论文笔记:UrbanGPT: Spatio-Temporal Large Language Models

1 intro 时空预测的目标是预测并洞察城市环境随时间和空间不断变化的动态。其目的是预见城市生活多个方面的未来模式、趋势和事件&#xff0c;包括交通、人口流动和犯罪率。虽然已有许多努力致力于开发神经网络技术&#xff0c;以准确预测时空数据&#xff0c;但重要的是要注意…

springboot是什么?

可以应用于Web相关的应用开发。 选择合适的框架&#xff0c;去开发相关的功能&#xff0c;会有更高的效率。 为什么Spring Boot才是你该学的!学java找工作必会技能!在职程序员带你梳理JavaEE框架_哔哩哔哩_bilibili java工程师的必备技能 Spring是Java EE领域的企业级开发宽…

万兆网络的十字路口:电口还是光模块?

&#x1f335;在构建高速、高效的网络系统时&#xff0c;选择正确的连接技术至关重要。万兆电口&#xff08;10GBASE-T&#xff09;和万兆光模块&#xff08;SFP&#xff09;是目前市场上两种主流的高速网络解决方案。它们各有优势&#xff0c;但在不同的应用场景和需求下&…

稀碎从零算法笔记Day54-LeetCode:39. 组合总和

题型&#xff1a;数组、树、DFS、回溯 链接&#xff1a;39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数…

在PostgreSQL中如何进行全文搜索,以及如何优化全文搜索性能?

文章目录 如何进行全文搜索1. 创建全文搜索向量2. 执行全文搜索查询 如何优化全文搜索性能1. 使用GIN索引2. 限制搜索范围3. 优化文本处理4. 使用并发搜索5. 监控和调整配置 在PostgreSQL中&#xff0c;全文搜索通常通过使用tsvector和tsquery类型&#xff0c;以及to_tsvector和…

安居水站:水站经营秘籍:年入30万不是梦。水站创业指南。

在这个快节奏的社会里&#xff0c;初创企业家们总是在寻找一条明路&#xff0c;以在竞争激烈的市场中立足。为了帮助他们更好地实现这一目标&#xff0c;我根据经验决定制定一份水站经营指导手册。这份手册将详细阐述如何从零起步&#xff0c;如何运营&#xff0c;如何进行市场…