C++——特殊类设计

目录

一.不能被拷贝的类

1.C++98做法

2.C++11做法

二.只能在堆上实例化的类

1.实现方式一

2.实现方式二

 三.只能在栈上创建的对象

四.不能被继承的类

1.C++98方式

2.C++11方式

五.只能创建一个对象的类

1.设计模式

2.单例模式


一.不能被拷贝的类

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

1.C++98做法

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

这样做的原因有两个:

  1. 只声明不定义:防止编译器自己生成拷贝构造函数以及赋值运算符重载,防止成员函数内部拷贝
  2. 设置成私有:防止别人在外部定义。

class Bancopy
{
public:Bancopy(int x):_x(x){}
private:Bancopy(Bancopy& obj);Bancopy& operator=(Bancopy& obj);
private:int _x;
};

2.C++11做法

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

class Bancopy
{
public:Bancopy(int x):_x(x){}Bancopy(Bancopy& obj) = delete;Bancopy& operator=(Bancopy& obj) = delete;
private:int _x;
};

二.只能在堆上实例化的类

1.实现方式一

  1. 将析构函数私有,构造函数公有化。
  2. 凡是需要编译器自动调用析构函数释放的对象都是不可以创建的,只有堆空间创建的对象可以手动释放对象空间。
  3. 提供一个共有函数,Destory,用于对象的析构。 
//思路一,将析构函数私有化
class HeapOnly
{
public:HeapOnly(int x):_x(x){}void Destory(){cout << "delete this" << endl;delete this;}
private:~HeapOnly(){}
private:int _x;
};

 测试代码:

int main()
{//HeapOnly t1(100);//对象无法自动调用析构函数//static HeapOnly t2(100);//对象无法自动调用析构函数//手动释放对象空间HeapOnly* t = new HeapOnly(100);t->Destroy();return 0;
}

2.实现方式二

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

//思路二,将构造函数私有化
class HeapOnly
{
public:static HeapOnly* CreateObj(int x){return new HeapOnly(x);}void Destroy(){cout << "delete this" << endl;delete this;}HeapOnly(HeapOnly& Obj) = delete;HeapOnly& operator=(HeapOnly& Obj) = delete;private:HeapOnly(int x):_x(x){}
private:int _x;
};

测试代码:

int main()
{//手动释放对象空间HeapOnly* t = HeapOnly::CreateObj(100);//HeapOnly t2 = (*t); error//t2 = *t; errort->Destroy();return 0;
}

 三.只能在栈上创建的对象

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

class StackOnly
{
public:static StackOnly CreateObj(int x){return  StackOnly(x);}StackOnly& operator=(StackOnly& Obj) = delete;private:StackOnly(int x):_x(x){}
private:int _x;
};

缺陷:对于静态对象我们没有办法阻止创建,因为我们通过静态的CreateObj也是需要传值返回的。如果将拷贝构造封住,换成移动构造,可以将普通的对象赋值给静态的对象拦截住,但是对于move之后的普通对象赋值给静态对象。

class StackOnly
{
public:static StackOnly CreateObj(int x){return  StackOnly(x);}StackOnly(StackOnly&& Obj) {_x = Obj._x;}StackOnly(StackOnly& Obj) = delete;StackOnly& operator=(StackOnly& Obj) = delete;private:StackOnly(int x):_x(x){}
private:int _x;
};

int main()
{StackOnly t = StackOnly::CreateObj(100);//StackOnly* pt = new StackOnly(200); error //static StackOnly t1 = t; //error static StackOnly t1 = move(t);//没办法阻止return 0;
}

四.不能被继承的类

1.C++98方式

C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承。派生类在对于基类的那部分数据回去调用基类的构造函数来完成,如果基类的构造函数变成私有,那么派生类就无法调用构造。接入派生类无法创建对象。

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

2.C++11方式

final关键字,final修饰类,表示该类不能被继承。

class base final
{
public:base(){}
private:};

五.只能创建一个对象的类

1.设计模式

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的
总结
。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打
仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后
来孙子就总结出了《孙子兵法》。孙子兵法也是类似。
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模
式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

2.单例模式

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

  • 饿汉模式

就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。

可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。

//单例模式——饿汉模式
class Singleton
{
public:static Singleton* GetSingleton(){return singleton;}vector<string> &get_sing_list(){return _sing_list;}void showlist(){for (auto e : _sing_list){cout << e << endl;}}
private://构造函数Singleton(){}Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;
private:vector<string> _sing_list;static Singleton* singleton;
};
//初始化的是类内部成员,可以访问私有的构造函数
//在没有进入主函数的时候,单例对象已经实例化完成
Singleton* Singleton::singleton = new Singleton;

 测试代码:

int main()
{Singleton* singleton = Singleton::GetSingleton();singleton->get_sing_list().push_back("《冰雨》——刘德华");singleton->get_sing_list().push_back("《月光》——胡彦斌");singleton->get_sing_list().push_back("《倒带》——周杰伦");singleton->get_sing_list().push_back("《呓语》——毛不易");singleton->showlist();return 0;
}

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

  • 懒汉模式

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

优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控
制。

//单例模式——懒汉模式
class Singleton
{
public:static Singleton* GetSingleton(){if (singleton == nullptr)//防止因为每次创建对象都要加锁带来的性能上的损耗{_mutex.lock();//防止多线程创建的时候,出现并发问题if (singleton == nullptr){singleton = new Singleton;}_mutex.unlock();}return singleton;}vector<string> &get_sing_list(){return _sing_list;}void showlist(){for (auto e : _sing_list){cout << e << endl;}}
private://构造函数Singleton(){i++;}Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;
private:static mutex _mutex;vector<string> _sing_list;static Singleton* singleton ;
};Singleton* Singleton::singleton = nullptr;
mutex Singleton::_mutex;

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

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

相关文章

visual studio Qt 开发环境中手动添加 Q_OBJECT 导致编译时出错的问题

问题简述 创建项目的时候&#xff0c;已经添加了类文件&#xff0c;前期认为不需要信号槽&#xff0c;就没有添加宏Q_OBJECT,后面项目需要&#xff0c;又加入了宏Q_OBJECT&#xff0c;但是发现只是添加了一个宏Q_OBJECT&#xff0c;除此之外没有改动其它的代码&#xff0c;原本…

基于springboot实现地方废物回收机构平台管理系统【项目源码+论文说明】

基于springboot实现地方废物回收机构管理系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把地方废物回收机构管理与现在网络相结合&#xff0c;利用java技术建设地方废物回收机构管理系统&#xff0c;实现地方废物回收机构的信息化。则对于进一步提高地方废物回收机…

如何提高广告投放转化率?Share Creators 资产库与Appsflyer营销数据的全面结合

如何提高广告投放转化率&#xff1f;Share Creators 资产库与Appsflyer营销数据的全面结合 全球经济进入了低迷期。 营销成本越来越高&#xff0c; 营销需要更务实&#xff0c;注重投入产出比。众所周知&#xff0c;除了渠道、客群画像以外&#xff0c; 优秀的广告设计图&#…

c进阶测试题

选择题 1.请问该程序的输出是多少&#xff08;C&#xff09; #include<stdio.h> int main(){unsigned char i 7;int j 0;for(;i > 0;i - 3){ j;} printf("%d\n", j);return 0; }A. 2 B. 死循环 C. 173 D. 172 首先unsigned char型是不会为负数&#xff…

flask入门(四)前后端数据传输

文章目录 1、flask后端接收来自前端的数据1&#xff09;如果前端提交的方法为POST2&#xff09;如果前段提交的方法是GET 2、flask后端向前端传数据3、案例参考文献 1、flask后端接收来自前端的数据 1&#xff09;如果前端提交的方法为POST 后端接收时的代码&#xff1a; xx…

我试图扯掉这条 SQL 的底裤。只能扯一点点,不能扯多了

之前不是写分页嘛,分页肯定就要说到 limit 关键字嘛。 然后我啪的一下扔了一个链接出来: https://dev.mysql.com/doc/refman/8.0/en/limit-optimization.html 这个链接就是 MySQL 官方文档,这一章节叫做“对 Limit 查询的优化”,针对 limit 和 order by 组合的场景进行了较…

【MySQL】存储引擎

存储引擎 查看存储引擎设置表的存储引擎创建表时指定存储引擎修改表的存储引擎 引擎介绍InnoDB引擎: 具备外键支持的十五存储引擎MyISAM引擎: 主要的非事务处理存储引擎Archive引擎: 用于数据存档Blackhole引擎: 丢弃写操作,读操作返回空内容CSV引擎: 读取数据时,以逗号分隔各个…

redis底层数据结构

总所周知&#xff0c;redis支持五种数据类型String、Hash、List、Set、ZSet。在支持这些复杂数据结构的同时&#xff0c;redis不仅需要保证读写的性能&#xff0c;还能提供各种微操作&#xff0c;比如直接修改Hash字典中的某个field的值&#xff0c;或者直接往ZSet中插入某个值…

Failed to start The nginx HTTP and reverse proxy server.

本章教程主要分享一下&#xff0c;当nginx 启动时&#xff0c;遇到报这个错误时的一个解决问题思路。 目录 1、观察报错信息 2、尝试性解决 1、观察报错信息 根据日志的信息&#xff0c;我们至少可以知道2个比较信息。 1、操作用户执行命令是在非root权限下进行操作的。 2、Ad…

Xcode14创建github远程仓库Token

1.点击Create a Token on GitHub 2.在打开的网页中,登陆GitHub 3.点击生成Token 这是不能为空 4.Token创建成功如下: 5.复制Token到Xcode然后点击Sign In登陆 正在创建远程我仓库 正在将本地仓库代码推入远程仓库 创建成功

C++项目——云备份-②-第三方库认识

文章目录 专栏导读1. json 认识1.1 JSON 数据结构的特点 2. jsoncpp库认识3. json实现序列化案例4. json实现反序列化案例5. bundle文件压缩库认识6. bundle库实现文件压缩案例7.bundle库实现文件解压缩案例8.httplib库认识9. httplib库搭建简单服务器案例10. httplib库搭建简单…

YOLO目标检测——密集人群人头检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;在公共场所&#xff0c;如车站、商场、景区等&#xff0c;可以通过人头目标检测技术来监测人群流量数据集说明&#xff1a;人头检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注…

python实现excel的数据提取

一文带你实现excel表格的数据提取 今天记录一下如何使用python提取Excel中符合特定条件的数据 在数据处理和分析的过程中&#xff0c;我们经常需要从Excel表格中提取特定条件下的数据。Python的pandas库为我们提供了方便的方法来进行数据查询和过滤。 Pandas 是 Python 语言…

SELECT COUNT(*) 会造成全表扫描吗?

前言 SELECT COUNT(*)会不会导致全表扫描引起慢查询呢&#xff1f; SELECT COUNT(*) FROM SomeTable 网上有一种说法&#xff0c;针对无 where_clause 的 COUNT(*)&#xff0c;MySQL 是有优化的&#xff0c;优化器会选择成本最小的辅助索引查询计数&#xff0c;其实反而性能…

基于深度学习实现一张单图,一个视频,一键换脸,Colab脚本使用方法,在线版本,普通人也可以上传一张图片体验机器学习一键换脸

基于深度学习实现一张单图,一个视频,一键换脸,Colab脚本使用方法,在线版本,普通人也可以上传一张图片体验机器学习一键换脸。 AI领域人才辈出,突然就跳出一个大佬“s0md3v”,开源了一个单图就可以进行视频换脸的项目。 项目主页给了一张换脸动图非常有说服力,真是一图…

Fiber Golang:Golang中的强大Web框架

揭示Fiber在Go Web开发中的特点和优势 在不断发展的Web开发领域中&#xff0c;选择正确的框架可以极大地影响项目的效率和成功。介绍一下Fiber&#xff0c;这是一款令人印象深刻的Golang&#xff08;Go语言&#xff09;Web框架。以其飞快的性能和强大的特性而闻名&#xff0c;…

【算法训练-动态规划 一】【应用DP问题】零钱兑换、爬楼梯、买卖股票的最佳时机I、打家劫舍

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【动态规划】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

VR虚拟现实技术在法院技能培训中的应用

开展法治宣传教育&#xff0c;是全面贯彻落实科学发展观的重要决策&#xff0c;也是保障和促进经济设备会发展和实施“十一五”规划的内在要求。为了让全民法治文化宣传深入人们群众中&#xff0c;突破性地采用VR虚拟现实、web3d开发和三维仿真技术&#xff0c;开发线上法治文化…

大数据技术学习笔记(二)—— Hadoop运行环境的搭建

目录 1 准备模版虚拟机hadoop1001.1 修改主机名1.2 修改hosts文件1.3 修改IP地址1.3.1 查看网络IP和网关1.3.2 修改IP地址 1.4 关闭防火墙1.5 创建普通用户1.6 创建所需目录1.7 卸载虚拟机自带的open JDK1.8 重启虚拟机 2 克隆虚拟机3 在hadoop101上安装JDK3.1 传输安装包并解压…

<蓝桥杯软件赛>零基础备赛20周--第1周

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列。 每个周末发1个博客&#xff0c;共20周&#xff0c;到明年3月初结束。跟上本博客的节奏&#xff0c;省赛三等奖跑不掉。 每周3…