当前位置: 首页 > news >正文

c++中的特殊类设计

文章目录

  • 1.请设计一个类,不能被拷贝
  • 2. 请设计一个类,只能在堆上创建对象
  • 3. 请设计一个类,只能在栈上创建对象
  • 4. 请设计一个类,不能被继承
  • 5. 请设计一个类,只能创建一个对象(单例模式)

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

拷贝只会发生在两种场景中:拷贝构造函数以及赋值运算符的重载;因此想要让一个类禁止拷贝,只需要让该类不能够调用赋值运算符的重载以及拷贝构造函数即可
c++98的方法:
将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可

class People
{// ...private:People(const People&);People& operator=(const People&);//...
};

原因:

  1. 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就不能够禁止拷贝了。
  2. 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就不会防止成员函数的内部拷贝。
    c++11的方法:
    c++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上delete,表示让编译器删除掉该默认成员函数。
class People
{// ...People(const People&)=delete;People& operator=(const People&)=delete//...
};

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

实现方式:

  1. 将类的构造函数私有,拷贝构造声明成私有,防止别人调用拷贝在栈上生成类对象;
  2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。
class HeapOnly
{
public:static HeapOnly* CreatObject(){return new HeapOnly;}
private:HeapOnly(){};//c++98//1.只声明不实现,因为实现可能会很复杂,而你本身不需要//2.声明成私有HeapOnly(const HeapOnly&);//or//c++11HeapOnly(const HeapOnly&)=delete;
};

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

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

class StackOnly
{
public:static StackOnly CreatObj(){return StackOnly();}	// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉// StackOnly obj = StackOnly::CreateObj();// StackOnly* ptr3 = new StackOnly(obj);void* operator new(size_t size) = delete;//new和delete操作符用于在堆(heap)内存上创建和删除对象void operator delete(void* p) = delete;
private:StackOnly() :_a(0){}
private:int _a;
}

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

C++98方式

// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}	
};

C++11方法
final关键字,final修饰类,表示该类不能被继承。
class A final
{
// …
};

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

设计模式:
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的
总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打
仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后
来孙子就总结出了《孙子兵法》。孙子兵法也是类似。
使用设计模式的目的为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样

单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个
访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置
信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再
通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
单例模式有两种实现模式:
饿汉模式
就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。

饿汉模式
优点:简单
缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{public:static Singleton* GetInstance(){return &m_instance;}private:// 构造函数私有Singleton(){};// C++98 防拷贝Singleton(Singleton const&);Singleton& operator=(Singleton const&);// or// C++11Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;static Singleton m_instance;
};Singleton Singleton::m_instance;  // 在程序入口之前就完成单例对象的初始化

如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避
免资源竞争,提高响应速度更好。
懒汉模式
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取
文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,
就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

// 懒汉
// 优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控
制。
// 缺点:复杂
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Singleton
{
public:static Singleton* GetInstance() {// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全if (nullptr == m_pInstance) {m_mtx.lock();if (nullptr == m_pInstance) {m_pInstance = new Singleton();}m_mtx.unlock();}return m_pInstance;}
// 实现一个内嵌垃圾回收类  class CGarbo {public:~CGarbo(){if (Singleton::m_pInstance)delete Singleton::m_pInstance;}};// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象static CGarbo Garbo;
private:// 构造函数私有Singleton(){};// 防拷贝Singleton(Singleton const&);Singleton& operator=(Singleton const&);static Singleton* m_pInstance; // 单例对象指针static mutex m_mtx;  //互斥锁
};
Singleton* Singleton::m_pInstance = nullptr;
Singleton::CGarbo Garbo;
mutex Singleton::m_mtx;
int main()
{thread t1([]{cout << &Singleton::GetInstance() << endl; });thread t2([]{cout << &Singleton::GetInstance() << endl; });t1.join();t2.join();cout << &Singleton::GetInstance() << endl;cout << &Singleton::GetInstance() << endl;return 0;
}

相关文章:

c++中的特殊类设计

文章目录 1.请设计一个类&#xff0c;不能被拷贝2. 请设计一个类&#xff0c;只能在堆上创建对象3. 请设计一个类&#xff0c;只能在栈上创建对象4. 请设计一个类&#xff0c;不能被继承5. 请设计一个类&#xff0c;只能创建一个对象(单例模式) 1.请设计一个类&#xff0c;不能…...

开源更安全? yum源配置/rpm 什么是SSH?

文章目录 1.开放源码有利于系统安全2.yum源配置&#xff0c;这一篇就够了&#xff01;(包括本地&#xff0c;网络&#xff0c;本地共享yum源)3.rpm包是什么4.SSH是什么意思&#xff1f;有什么功能&#xff1f; 1.开放源码有利于系统安全 开放源码有利于系统安全 2.yum源配置…...

庖丁解牛:NIO核心概念与机制详解 04 _ 分散和聚集

文章目录 Pre概述分散/聚集 I/O分散/聚集的应用聚集写入Code Pre 庖丁解牛&#xff1a;NIO核心概念与机制详解 01 庖丁解牛&#xff1a;NIO核心概念与机制详解 02 _ 缓冲区的细节实现 庖丁解牛&#xff1a;NIO核心概念与机制详解 03 _ 缓冲区分配、包装和分片 概述 分散/聚…...

Java读写Jar

Java提供了读写jar的类库Java.util.jar&#xff0c;Java获取解析jar包的工具类如下&#xff1a; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; import java.util.HashMap; import …...

【四元数简述】

w cos(theta/2) x ax * sin(theta/2) y ay * sin(theta/2) z az * sin(theta/2) 向量(x,y,z)是旋转轴 a 是任意正数 theta是旋转角度。 上面就是一个四元数表示旋转。 如何使用 空间中向量&#xff08;1,2,3&#xff09;扩展为&#xff08;0,1,2,3&#…...

ClickHouse SQL 查询优化

1 单表查询 1.1 Prewhere替代where Prewhere和where语句的作用相同&#xff0c;用来过滤数据。不同之处在于prewhere只支持 *MergeTree 族系列引擎的表&#xff0c;首先会读取指定的列数据&#xff0c;来判断数据过滤&#xff0c;等待数据过滤之后再读取select 声明的列字段来补…...

「Verilog学习笔记」数据选择器实现逻辑电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 将变量A、B接入4选1数据选择器选择输入端S0 S1。将变量C分配在数据输入端。从表中可以看出输出L与变量C的关系。 当AB00时选通D0而此时L0&#xff0c;所以数据端D0接0…...

【Go入门】Web工作方式

【Go入门】 Web工作方式 我们平时浏览网页的时候,会打开浏览器&#xff0c;输入网址后按下回车键&#xff0c;然后就会显示出你想要浏览的内容。在这个看似简单的用户行为背后&#xff0c;到底隐藏了些什么呢&#xff1f; 对于普通的上网过程&#xff0c;系统其实是这样做的&…...

综述:目标检测二十年(机翻版)(未完

原文地址 20年来的目标检测&#xff1a;一项调查 摘要关键词一 介绍二 目标检测二十年A.一个目标检测的路线图1)里程碑&#xff1a;传统探测器Viola Jones探测器HOG检测器基于可变形零件的模型&#xff08;DPM&#xff09; 2)里程碑&#xff1a;基于CNN的两阶段探测器RCNNSPPN…...

quinn源码解析:QUIC数据包是如何发送的

quinn源码解析&#xff1a;QUIC数据包是如何发送的 简介QUIC协议中的概念endpoint&#xff08;端点&#xff09;connection&#xff08;连接&#xff09;Stream&#xff08;流&#xff09;Frame (帧) 发包过程解析SendStream::write_allConnectionDriverEndpointDriver 简介 q…...

scss的高级用法——循环

周末愉快呀&#xff01;一起来学一点简单但非常有用的css小知识。 最近在一个项目中看到以下css class写法&#xff1a; 了解过tailwind css或者unocss的都知道&#xff0c;从命名就可以看出有以下样式&#xff1a; font-size: 30pxmargin-left: 5px;margin-top: 10px; 于是…...

Linux安装Chrome浏览器 -linux安装choeme

Linux 操作系统一般自带的浏览器是 FireFox&#xff0c;不过有些用户可能更喜欢 Google 出品的 Chrome 浏览器。本教程将介绍如何在 Linux 系统上安装 Chrome 浏览器&#xff0c;以及可能会遇到的一些问题解决方案。 下载 Chrome 安装包 需要下载 Chrome 的安装包。可以在 Go…...

六大排序(插入排序、希尔排序、冒泡排序、选择排序、堆排序、快速排序)未完

文章目录 排序一、 排序的概念1.排序&#xff1a;2.稳定性&#xff1a;3.内部排序&#xff1a;4.外部排序&#xff1a; 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四、交换排序1.冒泡排序2.快速排序…...

JVM垃圾回收相关概念

目录 一、System.gc()的理解 二、内存溢出与内存泄露 &#xff08;一&#xff09;OOM &#xff08;二&#xff09;内存泄露 三、StopTheWorld 四、垃圾回收的并行与并发 五、安全点与安全区域 &#xff08;一&#xff09;安全点 &#xff08;二&#xff09;安全区域 …...

C++各种字符转换

C各种字符转换 一.如何将char数组转化为string类型二. string转char数组&#xff1a;参考 一.如何将char数组转化为string类型 在C中&#xff0c;可以使用string的构造函数或者赋值操作符来将char数组转换为string类型。 方法1&#xff1a;使用string的构造函数 const char* c…...

MSSQL-逻辑级常用命令

--SQL Server 查询表的记录数 --one: 使用系统表. SELECT object_name (i.id) TableName, rows as RowCnt FROM sysindexes i INNER JOIN sysObjects o ON (o.id i.id AND o.xType U ) WHERE indid < 2 ORDER BY rows desc ————————————…...

【如何学习Python自动化测试】—— 时间等待

3 、 时间等待 在做自动化测试时&#xff0c;难免会碰到一些问题&#xff0c;比如你在脚本中操作某个对象时&#xff0c; 页面还没有加载出来&#xff0c;你的操作语句已经被执行&#xff0c;从而导致脚本执行失败&#xff0c;针对这样的问题 webdriver 提供了等待操作&#xf…...

《数字图像处理-OpenCV/Python》连载(44)图像的投影变换

《数字图像处理-OpenCV/Python》连载&#xff08;44&#xff09;图像的投影变换 本书京东优惠购书链接&#xff1a;https://item.jd.com/14098452.html 本书CSDN独家连载专栏&#xff1a;https://blog.csdn.net/youcans/category_12418787.html 第 6 章 图像的几何变换 几何变…...

AI机器学习 | 基于librosa库和使用scikit-learn库中的分类器进行语音识别

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…...

Asp.net MVC Api项目搭建

整个解决方案按照分层思想来划分不同功能模块&#xff0c;以提供User服务的Api为需求&#xff0c;各个层次的具体实现如下所示&#xff1a; 1、新建数据库User表 数据库使用SQLExpress版本&#xff0c;表的定义如下所示&#xff1a; CREATE TABLE [dbo].[User] ([Id] …...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...