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,一经查实,立即删除!

相关文章

达梦数据库的DMRMAN工具-管理备份(备份集查看)

达梦数据库的DMRMAN工具-管理备份&#xff08;备份集查看&#xff09; 管理备份一个重要的目的是删除不再需要的备份。DMRMAN 工具提供 SHOW、 CHECK、REMOVE、 LOAD 等命令分别用来查看、校验、删除和导出备份集。下文将对这些命令进行详细介绍。若命令中指定了 dm.ini&#…

如何在原生项目中集成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…

vue3-setup与vue2的data共存

文章目录 前言一、vue3的setup响应式状态生命周期钩子示例注意事项 二、与vue2 的data 共存setup 与 data 的区别setup 与 data 的共存注意事项示例 前言 vue3 setup 学习 一、vue3的setup Vue 3 的 setup 函数是 Composition API 的核心&#xff0c;它提供了一种新的方式来使…

《设计模式之美》- 总结

《设计模式之美》- 总结 第一章 概述 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版…

探索Java设计模式:组合模式

探索Java设计模式&#xff1a;深入理解与实践组合模式 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它将对象组织成树形结构&#xff0c;以表示“部分-整体”的层次关系&#xff0c;并允许客户端以一致的方式处理单个对象和对象集合。…

Python 计算给定公式的真值表

在Python中&#xff0c;计算给定逻辑公式的真值表可以通过编写一个简单的函数来实现&#xff0c;该函数遍历所有可能的输入变量组合&#xff0c;并计算表达式的值。以下是一个使用Python计算逻辑表达式真值表的示例&#xff1a; def calculate_truth_table(variables, express…

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是由溢信科技股份有限公司开发的一款终端安全管…

redis的订阅与发布功能

1&#xff1a;yml配置 server:port: 8082 spring:application:name: order-nacosredis:host: 127.0.0.1password: 123456database: 0 logging:level:root: info2&#xff1a;pom.xm依赖 <parent><groupId>org.springframework.boot</groupId><artifactId…

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/…

js html生成图片

js html生成图片 下载依赖 npm install html2canvas引入依赖 import html2canvas from "html2canvas"代码 export const handleHtml2Img async (el, options {}) > {let canvas await new html2canvas(el, options);let imgUrl canvas.toDataURL();return…