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.hqwc.cn/news/636130.html

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

相关文章

SpringCloud系列(8)--将服务提供者Provider注册进Eureka Server

前言&#xff1a;上一章节我们介绍了Eureka服务端的安装与配置&#xff0c;本章节则介绍关于微服务如何入职Eureka Server Eureka架构原理图 1、修改provider-payment8001子模块的pom.xml文件&#xff0c;引入Eureka Clinet的依赖&#xff0c;然后reolad一下&#xff0c;下载依…

Docker - HelloWorld

原文地址&#xff0c;使用效果更佳&#xff01; Docker - HelloWorld | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-helloworld.html 开始之前 在学习本小节之前&#xff0c;你必须确保你正确安装了 Docker&#xff0c;正确安装 Docker 是后续学习的…

幻方量化开源国内首个MoE大模型,全新架构、免费商用

幻方量化开源国内首个MoE大模型&#xff0c;全新架构、免费商用 OSC OSC开源社区 2024-01-12 19:01 广东 幻方量化旗下组织深度求索发布了国内首个开源 MoE 大模型 —— DeepSeekMoE&#xff0c;全新架构&#xff0c;免费商用。 今年 4 月&#xff0c;幻方量化发布公告称&…

专题【二分查找】刷题日记

题目列表 4. 寻找两个正序数组的中位数 33. 搜索旋转排序数组 34. 在排序数组中查找元素的第一个和最后一个位置 35. 搜索插入位置 69. x 的平方根 167. 两数之和 II - 输入有序数组 209. 长度最小的子数组 222. 完全二叉树的节点个数 287. 寻找重复数 2023.04.14 4. 寻找两…

Python-VBA函数之旅-hasattr函数

目录 一、hasattr函数的常见应用场景&#xff1a; 二、hasattr函数使用注意事项&#xff1a; 1、hasattr函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、hasattr函数的常见应用场…

Spring 事务实现方式:

Spring 事务实现方式&#xff1a; Spring并不直接支持事务&#xff0c;只有当数据库支持事务的时候&#xff0c;Spring才支持事务&#xff0c;Spring只不过简化了开发人员实现事务的开发步骤 Spring事务的实现方式有两种&#xff1a; 一、基于申明式事务&#xff1a; Service…

ORAN C平面 Section Extension 23

ORAN C平面Section扩展23用于任意symbol模式的调制压缩参数。此section扩展允许为一个或多个“SymPrbPatterns”指定多组“mcScaleReMask、csf和mcScaleOffset”值。“SymPrbPattern”用于指定一组PRB&#xff0c;这些PRB可以跨越使用prbPattern指定的整个PRB范围&#xff08;频…

MYSQL之增删改查(中)

前言&#xff1a; 以下是MySQL最基本的增删改查语句&#xff0c;很多IT工作者都必须要会的命令&#xff0c;也 是IT行业面试最常考的知识点&#xff0c;由于是入门级基础命令&#xff0c;所有所有操作都建立在单表 上&#xff0c;未涉及多表操作。 4、“查”——之单表查询 My…

滚动条详解:跨平台iOS、Android、小程序滚动条隐藏及自定义样式综合指南

滚动条是用户界面中的图形化组件&#xff0c;用于指示和控制内容区域的可滚动范围。当元素内容超出其视窗边界时&#xff0c;滚动条提供可视化线索&#xff0c;并允许用户通过鼠标滚轮、触屏滑动或直接拖动滑块来浏览未显示部分&#xff0c;实现内容的上下或左右滚动。它在保持…

中国人的谦逊与生俱来

中国人的谦逊是与生俱来的&#xff0c;我们从老子的《道德经》就能探知一二&#xff1a; 一、不自夸、不自傲 《道德经》原文&#xff1a;自见者不明&#xff1b;自是者不彰&#xff1b;自伐者无功&#xff1b;自矜者不长。&#xff08;第二十四章&#xff09; 译文&#xff…

音视频封装格式解析(1)——H264格式简析,I/P/B帧是什么?H264压缩原理

文章目录 1. H264编码参数2. H264编码原理2.1 压缩原理2.2 编码结构解析 3. NALU结构4. H264 annexb模式5. 补充说明5.1 I帧5.2 P帧5.3 B帧 1. H264编码参数 视频质量和⽹络带宽占⽤是相⽭盾的。通常情况下&#xff0c;视频流占⽤的带宽越⾼则视频质量也越⾼&#xff0c;需要的…

ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…