C++ 特殊类设计

news/2024/12/13 2:41:52/

目录

一.不允许被拷贝

二.只能在堆上创建对象

三.只能在栈上创建对象

四.不允许被继承

五.只能创建一个对象(单例模式)

1.饿汉模式

2.懒汉模式

3.比较


前言:一些对于类的设计,比如单例模式等,是比较有用的一种特殊类的设计。

一.不允许被拷贝

        拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。

     

        (1)C++98:将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。

class CopyBan
{
public:private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);
};

        (2)C++11:C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数。

class CopyBan
{
public:CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;
};

二.只能在堆上创建对象

① 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
② 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建

class HeapOnly
{
public:static HeapOnly* CreatObj(){return new HeapOnly;}HeapOnly(const HeapOnly&) = delete;private:// 构造函数私有HeapOnly(){}
};

三.只能在栈上创建对象

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

class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}StackOnly(const StackOnly&) = delete;
private:// 构造函数私有StackOnly(){}
};

四.不允许被继承

 C++98:

class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}
};

C++11:C++11给了final函数,如果继承就会报错

class A final
{};

五.只能创建一个对象(单例模式)

设计模式:

        设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。设计模式就像是代码中的孙子兵法。

        使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模
式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

单例模式:

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

        单例模式有两种实现模式:

1.饿汉模式

       无论之后用不用,程序启动时就创建一个唯一的实例对象。

class Singleton
{
public:static Singleton* GetInstance(){return _spInst;}
private:Singleton(){}Singleton(const Singleton&) = delete;// static Singleton _sInst; // 声明static Singleton* _spInst; // 声明int _a;
};// Singleton Singleton::_sInst; // 定义
Singleton* Singleton::_spInst = new Singleton; // 定义

        如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞争,提高响应速度更好

2.懒汉模式

        如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

第一种万能写法:

class Singleton
{
public:static Singleton* GetInstance(){// 保护第一次,后续不需要加锁// 双检查加锁if (_pInstance == nullptr){unique_lock<mutex> lock(_mtx);if (_pInstance == nullptr){_pInstance = new Singleton;}}return _pInstance;}private:// 构造函数私有Singleton(){};// C++11Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;static Singleton* _pInstance;static mutex _mtx;
};

第二种C++11写法:

class Singleton
{
public:static Singleton* GetInstance(){// 局部的静态对象,第一次调用时初始化// 在C++11之前是不能保证线程安全的// C++11之前局部静态对象的构造函数调用初始化并不能保证线程安全的原子性。// C++11的时候修复了这个问题,所以这种写法,只能在支持C++11以后的编译器上玩static Singleton _s;return &_s;}private:// 构造函数私有Singleton() {};// C++11Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;
};

3.比较

(1)饿汉模式特点

        较为简单,初始化顺序不确定,如果有依赖关系就会有问题。饿汉模式对象初始化满且多分饿汉单例对象会影响程序启动。

(2)懒汉模式特点

        较为复杂一点,第一次调用时需要初始化,可以控制初始化顺序,延迟加载初始化,不影响程序启动。


http://www.ppmy.cn/news/29027.html

相关文章

15个Spring扩展点,一般人知道的不超过5个!

Spring的核心思想就是容器&#xff0c;当容器refresh的时候&#xff0c;外部看上去风平浪静&#xff0c;其实内部则是一片惊涛骇浪&#xff0c;汪洋一片。Spring Boot更是封装了Spring&#xff0c;遵循约定大于配置&#xff0c;加上自动装配的机制。很多时候我们只要引用了一个…

在外包公司熬了 3 年终于进了字节,竭尽全力....

其实两年前校招的时候就往字节投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…

教育行业客户管理案例

近年来&#xff0c;CRM越来越普遍和受到关注&#xff0c;愈来愈多的企业开始引进CRM系统&#xff0c;诚然CRM的引进能在或多或少的问题上改变企业&#xff0c;更不乏其中一些企业在引进CRM后获得巨大改变的成功案例&#xff0c;本文将以其中一个案列作为案例讲解 XX艺术教育是一…

操作系统权限提升(二十四)之Linux提权-明文ROOT密码提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 操作系统权限提升(二十)之Linux提权-计划任务提权 操作系统权限提升(二十一)之Linux提权-环境变量劫持提权 操作系统权限提升(二十二)之Linux提权-SUDO滥用提权 操作系统权限…

【Java】String类

1. String内部声明 jdk8以前&#xff1a; private final char value[]; final&#xff1a;指明数组一旦初始化&#xff0c;其地址就不能改变 jdk9以后&#xff1a; private final byte[] value;&#xff0c;为节省内存空间而优化 final&#xff1a;指明数组一旦初始化&…

【深入浅出 Yarn 架构与实现】4-6 RM 行为探究 - 申请与分配 Container

本小节介绍应用程序的 ApplicationMaster 在 NodeManager 成功启动并向 ResourceManager 注册后&#xff0c;向 ResourceManager 请求资源&#xff08;Container&#xff09;到获取到资源的整个过程&#xff0c;以及 ResourceManager 内部涉及的主要工作流程。 一、整体流程 …

VUE前端常问面试题

文章目录一、VUE前端常问面试题二、文档下载地址一、VUE前端常问面试题 1、MVC和MVVM 区别 MVC&#xff1a;MVC全名是 Model View Controller&#xff0c;即模型-视图-控制器的缩写&#xff0c;一种软件设计典范。 Model(模型)&#xff1a;是用于处理应用程序数据逻辑部分。通…

【项目精选】病历管理系统设计与实现(源码+视频)

点击下载源码 企业财务管理系统主要用于电子病历来提高医院各项工作的效率和质量&#xff0c;促进医学科研、教学&#xff1b;减轻各类事务性工作的劳动强度&#xff0c;使他们腾出更多的精力和时间来服务于病人。本系统结构如下&#xff1a; 电子病例系统&#xff1a; 病人登…