c++学习(特殊类设计)[30]

只能在堆上创建对象的类

如果你想要确保对象只能在堆上创建,可以通过将析构函数声明为私有,并提供一个静态成员函数来创建对象。这样,类的实例化只能通过调用静态成员函数来完成,而无法直接在栈上创建对象。

以下是一个示例:

class HeapOnlyClass {
private:HeapOnlyClass() {} // 私有的构造函数,防止在栈上创建对象~HeapOnlyClass() {} // 私有的析构函数public:static HeapOnlyClass* createInstance() {return new HeapOnlyClass();}
};int main() {// 无法在栈上创建对象// HeapOnlyClass obj;// 只能通过静态成员函数创建对象HeapOnlyClass* obj = HeapOnlyClass::createInstance();// 使用对象...delete obj; // 释放堆上的对象return 0;
}

在上面的示例中,HeapOnlyClass 类的构造函数和析构函数都被声明为私有。这意味着在类的外部无法直接创建对象或销毁对象。

通过提供一个静态成员函数 createInstance(),我们可以在堆上创建对象。静态成员函数返回一个指向 HeapOnlyClass 对象的指针。在 main() 函数中,我们使用 createInstance() 函数来创建对象,并在使用完对象后通过 delete 关键字释放对象。

这样,我们就可以确保对象只能在堆上创建,而无法在栈上创建。

只能在栈上创建对象的类

如果你想要确保对象只能在栈上创建,可以将类的构造函数声明为私有,并提供一个静态成员函数来创建对象。这样,类的实例化只能通过调用静态成员函数来完成,而无法直接在堆上创建对象。

以下是一个示例:

class StackOnlyClass {
private:StackOnlyClass() {} // 私有的构造函数,防止在堆上创建对象public:static StackOnlyClass createInstance() {return StackOnlyClass();}
};int main() {// 无法在堆上创建对象// StackOnlyClass* obj = new StackOnlyClass();// 只能通过静态成员函数创建对象StackOnlyClass obj = StackOnlyClass::createInstance();// 使用对象...return 0;
}

在上面的示例中,StackOnlyClass 类的构造函数被声明为私有。这意味着在类的外部无法直接创建对象。

通过提供一个静态成员函数 createInstance(),我们可以在栈上创建对象。静态成员函数返回一个 StackOnlyClass 对象。在 main() 函数中,我们使用 createInstance() 函数来创建对象,并在使用完对象后,对象会自动被销毁。

这样,我们就可以确保对象只能在栈上创建,而无法在堆上创建。

单例模式(一个类之只能创建一个对象)

在这里插入图片描述
在这里插入图片描述
单例模式可以通过懒汉模式和饿汉模式来实现。下面我将为你解释这两种方式的实现。

  1. 懒汉模式:
    懒汉模式是指在需要获取实例时才会创建对象。实现懒汉模式的关键是延迟实例化,即在第一次调用获取实例的方法时才创建对象。
class LazySingleton {
private:static LazySingleton* instance;LazySingleton() {} // 私有构造函数public:static LazySingleton* getInstance() {if (instance == nullptr) {instance = new LazySingleton();}return instance;}
};LazySingleton* LazySingleton::instance = nullptr;

在上面的示例中,LazySingleton 类的构造函数被声明为私有,无法直接实例化对象。通过静态成员变量 instance 来保存类的唯一实例,并在 getInstance() 方法中进行延迟实例化。如果 instancenullptr,则创建一个新的 LazySingleton 对象。如果 instance 不为 nullptr,则直接返回现有的实例。

  1. 饿汉模式:
    饿汉模式是指在类加载时就创建对象,无需延迟实例化。实现饿汉模式的关键是在类定义中直接创建对象,并提供一个静态方法来获取这个实例。
class EagerSingleton {
private:static EagerSingleton* instance;EagerSingleton() {} // 私有构造函数public:static EagerSingleton* getInstance() {return instance;}
};EagerSingleton* EagerSingleton::instance = new EagerSingleton();

在上面的示例中,EagerSingleton 类的构造函数被声明为私有,无法直接实例化对象。通过静态成员变量 instance 在类定义中直接创建 EagerSingleton 对象。在 getInstance() 方法中,直接返回这个已经创建好的实例。

懒汉模式和饿汉模式都可以实现单例模式,但它们的区别在于实例化的时机。懒汉模式在第一次调用获取实例的方法时才创建对象,而饿汉模式在类加载时就创建对象。

懒汉模式和饿汉模式各有优点和缺点,下面我将为你详细解释。

懒汉模式的优点:

  1. 延迟实例化:懒汉模式在需要获取实例时才会创建对象,可以避免不必要的资源消耗。如果实例化对象的过程比较耗时,懒汉模式可以提高性能。
  2. 线程安全(加锁):在多线程环境下,懒汉模式可以通过加锁来保证只有一个线程能够创建实例。这样可以避免多个线程同时创建多个实例的问题。

懒汉模式的缺点:

  1. 线程安全(加锁):虽然懒汉模式可以通过加锁来保证线程安全,但是加锁会引入额外的开销,降低性能。
  2. 可能存在资源竞争:在多线程环境下,如果有多个线程同时判断实例为空,然后同时创建实例,就会导致资源竞争的问题。

饿汉模式的优点:

  1. 简单直观:饿汉模式在类加载时就创建了实例,不需要进行延迟实例化的逻辑,代码相对简单。
  2. 线程安全:在类加载时就创建了实例,因此不会存在多个线程同时创建实例的问题。

饿汉模式的缺点:

  1. 提前实例化:饿汉模式在类加载时就创建了实例,如果这个实例在后续的程序中没有被使用,就会造成资源的浪费。
  2. 无法处理异常:在饿汉模式下,如果在创建实例的过程中发生异常,无法通过捕获异常来处理,因为实例的创建是在类加载时进行的。

综上所述,懒汉模式适用于需要延迟实例化的场景,可以避免不必要的资源消耗;而饿汉模式适用于实例创建比较简单且在后续程序中会被使用的场景,可以保证线程安全。

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

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

相关文章

【PCIE】PCIE的驱动和pcie的端口驱动关系

pice驱动和pcie端口驱动区别 PCIe的端口服务驱动与PCIe驱动之间存在一定的关系,但它们是不同的概念。 PCIe驱动是用于管理和操作PCIe设备的驱动程序。它负责与硬件进行通信,并实现对PCIe设备的配置、数据传输以及其他相关操作。PCIe驱动通常涉及设备的…

【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)

一、说明 在上一篇博客中,我们讨论了原版RNN架构,也讨论了它的局限性。梯度消失是一个非常重要的缺点,它限制了RNN对较短序列的建模。香草 RNN 在相关输入事件和目标信号之间存在超过 5-10 个离散时间步长的时间滞时无法学习。这基本上限制了香草RNN在许多实际问题上的应用,…

NestJs Debug配置文件

(事缓则圆,人缓则安,语迟则贵,虎行似病,鹰立似睡。清俞万春《荡寇志》) {"version": "0.2.0","configurations": [{"type": "node","request": "launch","name": &quo…

基于LNMP架构搭建Discuz论坛

LNMP: L---->linux系统,操作系统。 N----->nginx网站服务(前端),提供前端的静态页面服务。同时具有代理、转发的作用。(转发就是转发后端请求,转发PHP),nginx没有处理动态资源的功能,他有…

IO模型-信号驱动IO

linux内核中存在一个信号SIGIO,这个信号就是用于实现信号驱动IO的。当应用程序中想要以信号驱动IO的模型读写硬件数据时,首先注册一个SIGIO信号的信号处理函数,当硬件数据就绪,硬件会发起一个中断,在硬件的中断处理函数中向当前进…

Plus 框架分页合理化问题

需要关闭 MyBatis Plus的分页合理化 RuoYi-Vue-Plus框架默认的Mybatis Plus分页拦截器配置是打开了分页合理化,这样会导致溢出的分页数据本来应该返回空数据,打开之后而会永远返回默认的前10条数据。 /*** mybatis-plus配置类(下方注释有插件介绍)** au…

CSS元素的显示模式

1、现在我想做成小米左侧边栏这样的效果,该怎么做呢? 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式: 5、用人进行划分可以分为男人和女人,根据男人和女人的特性进行相应的…

【ChatGPT 指令大全】怎么利用ChatGPT写报告

目录 选定切入角度 报告开头 大纲生成 草稿撰写 研究报告 提出反对观点 报告总结 研究来源 总结 随着人工智能技术的快速发展,自然语言处理技术在各个领域的应用越来越广泛。其中,ChatGPT作为目前最先进的自然语言处理模型之一,其强…

读写分离实现sharding-jdbc

一、背景 二、使用sharding-JDBC实现 1、导入依赖 2、配置文件(名字要对应) ​​​​​​​ 查询策略(轮询,指定哪个是主库哪个是从库) 允许bean定义覆盖

刷题笔记 day8

1004 最大连续1的个数 III 这道题要求将原数组中的0翻转成1,求出最大元素全是1的子数组长度,看这道题第一感觉还要将里面的0变成1,感觉这道题解决起来很麻烦,但是我们可以转变思路,找出其最大子数组,使得子…

手搓 LLM (不用rnn 不用attention 完全新思路)padding 实验

数据集地址 诗 实验过的几种策略 主体代码 import paddle import numpy as np from tqdm import tqdm import pandas as pd class EmMask(paddle.nn.Layer):def

8.6 day07 休息+剑指offer

文章目录 06从尾到头打印链表03数组中重复的数字04二维数组中的查找05 替换空格06重建二叉树背英语单词,看了二十页 06从尾到头打印链表 从尾到头遍历链表 方法一就是用栈来辅助,栈的结构是先进后出的,将链表中的元素加入到栈中去&#xff0…

无人驾驶实战-第八课(定位算法)

无人驾驶中定位的作用: 定位高精度地图:提供当前位置的静态环境感知 (车道线/交通指示牌/红绿灯/柱子/建筑物/等) 定位动态物体感知:将感知到的动态物体正确放入静态环境 定位获取位置姿态:用于路径规划/决…

单细胞测序基础知识

构建文库 上机测序 根据不同的荧光检测不同的碱基 质量控制(质控QC) 去除低质量的序列 表达定量 统计reads数,进而得到表达矩阵 标准化 让所有样本处在同一起跑线上 主成分分析PCA 图中每个点都代表一个样本,不同颜色…

pycharm、idea、golang等JetBrains其他IDE修改行分隔符(换行符)

文章目录 pycharm、idea、golang系列修改行分隔符我应该选择什么换行符JetBrains IDE,默认行分隔符 是跟随系统修改JetBrains IDE,默认行分隔符 pycharm、idea、golang系列修改行分隔符 一般来说,不同的开发环境和项目对换行格式的使用偏好不同: Windo…

解决vite+vue3项目npm装包失败

报错如下: Failed to remove some directories [ npm WARN cleanup [ npm WARN cleanup D:\\V3Work\\v3project\\node_modules\\vue, npm WARN cleanup [Error: EPERM: operation not permitted, rmdir D:\V3Work\v3project\node_modules\vue\reactivity\…

HTML5中Canvas学习笔记:Canvas

目录 一、HTML中Canvas画图strokeStyle 和 fillStyle 的区别是什么? 二、如何设置一幅canvas图中某个颜色透明? 三、H5 canvas中strokeRect参数如果是小数,如何处理? 四、H5 Canvas中如何画圆角矩形框? 一、HTML中…

设计模式行为型——迭代器模式

什么是迭代器模式 迭代器模式(Iterator Pattern)属于行为型模式,其提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示,即不需要知道集合对象的底层表示。编程环境中非常常用的设计模式。 迭代…

【驱动开发day8作业】

作业1&#xff1a; 应用层代码 #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <sys/ioctl.h>int main(int…

python --windows获取启动文件夹路径/获取当前用户名/添加自启动文件

如何使用Python获取计算机用户名 一、Python自带的getpass模块可以用于获取用户输入的密码&#xff0c;但是它同样可以用来获取计算机用户名。 import getpassuser getpass.getuser() print("计算机用户名为&#xff1a;", user)二、使用os模块获取用户名 Python的…