当前位置: 首页 > 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] …...

Windows 11/10下,Microsoft Store打不开?手把手教你用CheckNetIsolation命令批量解除UWP网络隔离

Windows 11/10下Microsoft Store无法连接的终极解决方案&#xff1a;CheckNetIsolation命令详解当你在Windows 11或10上突然发现Microsoft Store无法加载内容&#xff0c;或者Edge浏览器部分网页打不开&#xff0c;而其他网络连接却正常时&#xff0c;这很可能是因为UWP应用的网…...

k6性能测试实战:现代工程化压测方法论

1. 为什么是k6&#xff0c;而不是JMeter或Gatling&#xff1f;我第一次在生产环境压测中被JMeter拖垮&#xff0c;是在一个电商大促前夜。当时用20台云服务器搭起分布式集群&#xff0c;配置文件写了300多行&#xff0c;结果一跑起来内存飙到95%&#xff0c;GC频繁&#xff0c;…...

3大显示难题如何解决?用ColorControl实现专业级色彩管理

3大显示难题如何解决&#xff1f;用ColorControl实现专业级色彩管理 【免费下载链接】ColorControl Easily change NVIDIA display settings and/or control LG TVs 项目地址: https://gitcode.com/gh_mirrors/co/ColorControl ColorControl是一款强大的开源工具&#x…...

统信UOS 1070系统克隆实战:用自带工具给电脑做个‘替身’,换机迁移不求人

统信UOS 1070系统克隆实战&#xff1a;用自带工具给电脑做个‘替身’&#xff0c;换机迁移不求人当企业批量采购新设备或个人用户升级电脑时&#xff0c;如何快速将原有系统环境完整迁移到新硬件&#xff1f;传统方案往往依赖第三方工具&#xff0c;而统信UOS 1070内置的备份还…...

JMeter生产级接口测试实战:从环境配置到链路稳定性保障

1. 这不是又一篇“点点点”的JMeter入门指南&#xff0c;而是你真正能跑通、调得稳、查得清的接口测试实战手册很多人点开“JMeter教程”四个字&#xff0c;心里想的是&#xff1a;“不就是录个脚本、加个线程组、看个聚合报告吗&#xff1f;”——结果一上手&#xff0c;HTTP请…...

JTAG链式连接原理与ULINK2调试配置实战

1. JTAG设备链式连接的核心原理在嵌入式系统开发中&#xff0c;JTAG&#xff08;Joint Test Action Group&#xff09;接口是最常用的调试和编程接口之一。当系统中存在多个JTAG设备时&#xff0c;我们需要通过链式连接&#xff08;Chaining&#xff09;的方式将它们串联起来。…...

SUDO_HOST环境变量提权漏洞深度解析与防御

1. 这不是“又一个sudo漏洞”&#xff0c;而是权限模型的结构性失守你刚收到安全团队的紧急邮件&#xff0c;标题写着“高危Sudo漏洞&#xff08;CVE-2025-32463&#xff0c;CVSS 9.3&#xff09;&#xff1a;可提权至root并绕过主机限制&#xff0c;PoC已公开”。你下意识点开…...

Unity Android StreamingAssets路径原理与安全读取方案

1. 为什么这个路径问题会让人反复踩坑&#xff1f;在Unity Android项目里&#xff0c;StreamingAssets路径看似只是个字符串拼接问题&#xff0c;但实际开发中&#xff0c;它几乎是我接手过的每个中大型项目必修的“排障课”。不是因为代码难写&#xff0c;而是因为——它在不同…...

机器人导航核心技术:深度感知与传感器融合的工程实践

1. 项目概述&#xff1a;从“看见”到“理解”的机器人导航革命在机器人技术领域&#xff0c;导航能力是其智能化的核心体现。传统的机器人导航&#xff0c;无论是依赖预设地图的循迹&#xff0c;还是基于简单激光雷达的避障&#xff0c;都像是蒙着眼睛在熟悉的房间里摸索——虽…...

知识图谱与大语言模型协同:构建材料科学精准智能问答系统

1. 项目概述&#xff1a;当知识图谱遇见大语言模型“想象一下&#xff0c;未来有这样一个设备……个人可以存储他所有的书籍、记录和通信&#xff0c;并且它被机械化&#xff0c;可以以极高的速度和灵活性进行查阅。它是他记忆的一个放大的、亲密的补充。”——范内瓦布什&…...