【hello C++】特殊类设计

目录

一、设计一个类,不能被拷贝

二、设计一个类,只能在堆上创建对象

三、设计一个类,只能在栈上创建对象

四、请设计一个类,不能被继承

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



 C++🌷

一、设计一个类,不能被拷贝

拷贝只会发生在两个场景中:拷贝构造函数以及赋值运算符重载;
因此 想要让一个类禁止拷贝, 只需让该类不能调用 拷贝构造函数 以及 赋值运算符重载 即可
  • C++98
将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。
// C++98
class CopyBan
{private:Person(const CopyBan&);Person& operator=(const CopyBan&);
};
原因:
1. 设置成私有:如果只声明没有设置成 private ,用户自己如果在类外定义了,就可以不能禁止拷贝了;
2. 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就不会防止成员函数内部拷贝了。
  • C++11
C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟=delete,
表示让编译器删除掉该默认成员函数。
class CopyBan
{// ...CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;//...
};

二、设计一个类,只能在堆上创建对象

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

三、设计一个类,只能在栈上创建对象

  • 方法一:同上将构造函数私有化,然后设计静态方法创建对象返回即可。
class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉// StackOnly obj = StackOnly::CreateObj();// StackOnly* ptr3 = new StackOnly(obj);void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
private:StackOnly():_a(0){}private:int _a;
};

四、请设计一个类,不能被继承

  • C++98方式
// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}
};
  • C++11方法
final 关键字, final  修饰类,表示该类不能被继承。
class A  final
{// ....
};

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

设计模式:
设计模式( 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;
}

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

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

相关文章

移动端APP测试常见面试题精析

现在面试测试职位&#xff0c;要求非常全面&#xff0c;那么APP测试一般需要哪些技术呢&#xff1f;下面总结了APP测试常见面试题&#xff1a; 1.Android四大组件? Activity:描述UI&#xff0c;并且处理用户与机器屏幕的交互。应用程序中&#xff0c;一个Activity就相当于手…

MySql(干货)

写这篇博客的目的不是为了将介绍原理&#xff0c;而是为了Sql中的代码操作属实太多了&#xff0c;在这里进行一个汇总&#xff0c;方便查阅&#xff01;&#xff01;&#xff01; Sql分类 分类全称说明 DDL Data Definintion Language数据定义语言&#xff0c;用来定义数据库对…

解密Flink的状态管理:探索流处理框架的数据保留之道,释放流处理的无限潜能!

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 一、什么是状态二、应用场景三、Flink中状态的分类四、算子状态1. 列表状态&#xff08;List State&#xff09;2. 广播状态&#xff08;Broadcast State&#xff09; 五、键控状态1. Val…

【链表】经典链表题LeetCode

文章目录 160. 相交链表 简单&#x1f525;206. 反转链表 简单&#x1f525;876. 链表的中间结点 简单234. 回文链表 简单&#x1f525;141. 环形链表 简单&#x1f525;142. 环形链表 II 中等&#x1f525;21. 合并两个有序链表 简单&#x1f525;2. 两数相加 中等&#x1f52…

golang—面试题大全

目录标题 sliceslice和array的区别slice扩容机制slice是否线程安全slice分配到栈上还是堆上扩容过程中是否重新写入go深拷贝发生在什么情况下&#xff1f;切片的深拷贝是怎么做的copy和左值进行初始化区别slice和map的区别 mapmap介绍map的key的类型map对象如何比较map的底层原…

【Linux】线程同步和死锁

目录 死锁 什么是死锁 构成死锁的四个必要条件 如何避免死锁 线程同步 同步的引入 同步的方式 条件变量 条件变量的使用 整体代码 死锁 什么是死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源&#xff0c;但因互相申请被其他进程所占用不会释放 的资源而处…

GPU Microarch 学习笔记 [1]

WARP GPU的线程从thread grid 到thread block&#xff0c;一个thread block在CUDA Core上执行时&#xff0c;会分成warp执行&#xff0c;warp的颗粒度是32个线程。比如一个thread block可能有1024个线程&#xff0c;分成32个warp执行。 上图的CTA&#xff08;cooperative thre…

<dependency> idea中为什么这个变黄色

在IDE中&#xff0c;当你的代码出现黄色高亮时&#xff0c;通常表示存在警告或建议的提示。对于Maven的<dependency>标签来说&#xff0c;黄色高亮可能有以下几种原因&#xff1a; 依赖项未找到&#xff1a;黄色高亮可能表示IDE无法找到指定的依赖项。这可能是由于配置错…

Python实现SSA智能麻雀搜索算法优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新型的群智能优化算法&#xff0c;在2020年提出&a…

Docker入门指南:从零开始轻松掌握容器化技术【超级详细版】

文章目录 什么是Docker&#xff1f;平时应用部署的环境问题Docker解决依赖兼容问题Docker可以解决操作系统环境差异 Docker和虚拟机的区别Docker架构镜像容器仓库Docker的安装 Docker基本操作镜像操作容器操作数据卷&#xff08;容器数据管理&#xff09;1. 什么是数据卷2.数据…

开源,微信小程序 美食便签地图(FoodNoteMap)的设计与开发

目录 0 前言 1 美食便签地图简介 2 美食便签地图小程序端开发 2.1技术选型 2.2前端UI设计 2.3主页界面 2.4个人信息界面 2.5 添加美食界面 2.6美食便签界面 2.8 美食好友界面 2.9 美食圈子界面 2.10 子页面-店铺详情界面 2.11 后台数据缓存 2.12 订阅消息通知 2.1…

接口mock常用工具

在进行测试时&#xff0c;我们经常需要模拟接口数据&#xff0c;尤其是在前后端分离项目的开发中&#xff0c;在后端未完成开发时&#xff0c;前端拿不到后端的数据&#xff0c;就需要对后端返回的数据进行模拟。 如下一些工具&#xff0c;可以完成接口的mock。 Yapi 首先添…