【C++进阶】特殊类设计

news2024/11/23 21:23:07

🎇C++学习历程:入门


  • 博客主页:一起去看日落吗
  • 持续分享博主的C++学习历程
  • 博主的能力有限,出现错误希望大家不吝赐教
  • 分享给大家一句我很喜欢的话: 也许你现在做的事情,暂时看不到成果,但不要忘记,树🌿成长之前也要扎根,也要在漫长的时光🌞中沉淀养分。静下来想一想,哪有这么多的天赋异禀,那些让你羡慕的优秀的人也都曾默默地翻山越岭🐾。

在这里插入图片描述

🍁 🍃 🍂 🌿


目录

  • 🍁1. 请设计一个类,不能被拷贝
  • 🍁2. 请设计一个类,只能在堆上创建对象
  • 🍁3.设计一个类,只能在栈上创建对象
  • 🍁4. 设计一个类,不能被继承
  • 🍁5. 请设计一个类,只能创建一个对象(单例模式)

🍁1. 请设计一个类,不能被拷贝

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

  • C++98

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

class CopyBan
{
	// ...
private:
	CopyBan(const CopyBan&);
	CopyBan& 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;
	//...
};


🍁2. 请设计一个类,只能在堆上创建对象

实现方式:

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

作用:

  1. 设计单例模式的一个参考

class HeapOnly
{
public:
	static HeapOnly* CreateObject()
	{
		return new HeapOnly;
	}
	HeapOnly(const HeapOnly& ho) = delete;
private:
	HeapOnly()
		:_a(0)
	{}
private:
	int _a;
};

int main()
{
	//HeapOnly ho1;
	//HeapOnly* pho = new HeapOnly;

	HeapOnly* ptr = HeapOnly::CreateObject();
	//HeapOnly copy(*ptr);

	return 0;
}


🍁3.设计一个类,只能在栈上创建对象

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

因为new在底层调用void* operator new(size_t size)函数,只需将该函数屏蔽掉即可。

注意:也要防止定位new

class StackOnly
{
public:
	static StackOnly CreateObject()
	{
		return StackOnly();
	}
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;
private:
	StackOnly() 
		:_a(0)
	{}
private:
	int _a;
};

int main()
{
	//StackOnly* ptr1 = new StackOnly;

	StackOnly ptr2 = StackOnly::CreateObject();
	//StackOnly* ptr3 = new StackOnly(ptr2);
	return 0;
}


🍁4. 设计一个类,不能被继承

  • C++98

构造函数私有化,派生类中调不到基类的构造函数。则无法继承

// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:
	static NonInherit GetInstance()
	{
		return NonInherit();
	}
private:
	NonInherit()
	{}
};


  • C++11

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

class A final
{
// ....
};


🍁5. 请设计一个类,只能创建一个对象(单例模式)

设计模式:

  • 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后来孙子就总结出了《孙子兵法》。孙子兵法也是类似。

使用设计模式的目的

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

常见设计模式举例:

  • 迭代器模式:
    数据结构:数组,链表,二叉树,哈希表等
    访问和修改数据结构

暴露底层结构的缺点:

  • 访问不方便(需要熟悉底层结构)
  • 暴露底层结构,别人可以直接访问修改数据,不便于管理(举个栗子:栈,访问top位置的数据,但是我们的top位置的数据可能不是你需要的)
  1. 统一的方式封装访问结构,底层结构不暴露
  2. 可以使用统一的方式去轻松访问容器。不关心底层是树,还是链表等。

适配器模式:

  • 将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能在一起的工作的那些类可以一起工作。
  • 例如:stack,queue,priority_queue,reverse_iterator

单例模式:

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

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

  • 饿汉模式

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

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

class Chairman
{
public:
	void print()
	{
		cout << "对象调用" << endl;
	}
private:
	Chairman()  //私有构造函数
	{
		cout << "创建chairman类" << endl;
	}

public:
	static Chairman* singleman;  //类内声明chairman对象指针
};

Chairman* Chairman::singleman = new Chairman;  //类外进行初始化

int main()
{
	Chairman::singleman->print();
	return 0;
}

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


  • 懒汉模式

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

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

//
//  main.cpp
//  懒汉模式
//
//  Created by 卜绎皓 on 2022/12/24.
//

#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.coloradmin.cn/o/116855.html

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

相关文章

vue书写一个uni-app小程序

在本次文章中我来大致向大家介绍一下如何使用Hbuilder X来编写一个uni-app的小程序的项目&#xff0c;在此我只说编写的方法与方向&#xff0c;具体的操作留给大家去亲自实操哦。 1.起步&#xff08;创建一个uni-app框架&#xff09;&#xff1a; 首先&#xff0c;我们需要把…

低代码破解了软件开发“不可能三角”?我做了个测评...

老读者知道&#xff0c;K哥写了10几年代码&#xff0c;后来转做技术管理&#xff0c;现在是上市公司的技术高管。在我们软件行业有一条铁律&#xff1a;长周期、大规模的软件研发过程当中&#xff0c;想要维持良好的运作&#xff0c;需要解决&#xff1a;成本、效能、质量。而且…

Doris-查询(三)

目录1、查询设置1.1、增大内存1.2、修改超时时间1.3、查询重试和高可用1.3.1 代码方式1.3.2 JDBC Connector1.3.3 ProxySQL 方式2、简单查询3、Join查询3.1 Broadcast Join3.2 Shuffle Join&#xff08;Partitioned Join&#xff09;3.3 Colocation Join3.3.1 原理3.3.2 使用3.…

数字孪生电力3D可视化管控平台

当前&#xff0c;新一轮科技革命和产业变革加速演进&#xff0c;物联网、大数据、云计算、人工智能、5G等新一代信息技术快速发展。在众多技术手段中&#xff0c;数字孪生技术以虚实结合为主&#xff0c;架起虚拟世界与现实世界之间沟通的桥梁&#xff0c;为人们提供了更加便捷…

分享5款可以录屏的软件,录屏幕视频软件,亲测好用

很多小伙伴都会使用电脑来作为自己办公、娱乐、学习生活的工具。在电脑上安装录屏软件&#xff0c;可以轻松的协助我们进行网课录制、会议录制、影剧片段录制等。网络上的录屏软件有很多&#xff0c;今天小编分享5款亲测好用的录屏软件&#xff0c;一起来看看吧。 可以录屏的软…

数据结构进阶 二叉搜索树

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍二叉搜索树并且模拟实现之 二叉搜索树二叉搜索树的概念节点类二叉搜索树类私有成员构造函数拷贝构造函数赋值运算符重载函数…

若想学 HTML,应从何入手?

前言 个人信息&#xff1a; 大三 工商管理 逻辑算清晰 无编程基础 想学网页设计&#xff0c;打算从HTML开始 。 下面是问题&#xff1a; 需要先学一些更基础的语言&#xff08;如C之类的&#xff09;吗&#xff1f;有何建议&#xff1a; &#xff08;1&#xff09;看哪些书、泡…

无忧·企业邮筒功能介绍

应用介绍 企业邮筒&#xff0c;基于B/S模式的邮件客户端&#xff0c;采用JVS的统一用户体系&#xff0c;作为JVS的协同办公的应用之一。 产品特点 私有化部署、支持多邮件账户、将多个邮件客户端统一为web操作、 软件架构 软件架构说明&#xff0c;JVS-mailbox是作为JVS基…

服装实体店运营需要的所有软件,合集在此!(建议收藏)实体店运营 实体店运营干货 实体店运营全流程所需系统推荐

随着信息化普及程度越来越高&#xff0c;各行各业的运转速度都在加快&#xff0c;做生意的老板们也开始发现&#xff0c;单靠以前的人工管理已经完全不够用了。 尤其是服装实体店&#xff0c;款式分类多&#xff0c;库存又容易挤压&#xff0c;更加需要有科学的手段去管控日常的…

MyBatis学习 | 缓存机制

文章目录一、一级缓存1.1 简介1.2 一级缓存的失效情况二、二级缓存2.1 简介2.2 二级缓存的使用学习地址&#x1f517; https://www.bilibili.com/video/BV1mW411M737https://www.bilibili.com/video/BV1NE411Q7Nx官网文档 一、一级缓存 1.1 简介 &#x1f4ac;概述&#xff1…

Spring与SpringBoot

目录 前言 1、Spring能做什么 1.1、Spring的能力 1.2、Spring的生态 1.3、Spring5重大升级 1.3.1、响应式编程 1.3.2、内部源码设计 2、为什么用SpringBoot 2.1、SpringBoot优点 2.2、SpringBoot缺点 3、时代背景 3.1、微服务 3.2、分布式 分布式的困难 分布式的…

迪文DGUS智能屏如何轻松实现3D动画

三维立体的视觉效果已经被广泛应用于人机交互中&#xff0c;三维图形逼真的显示效果往往可以更加直接的传递出视觉信息&#xff0c;减少用户的信息解读门槛。 传统的三维立体静态、动态画面的显示往往对于 GPU 的图像处理性能、显示带宽有较高要求&#xff0c;GPU 需要完成图形…

使用gs_probackup进行数据库物理备份与恢复

概述 物理备份与恢复适用于数据量大的场景&#xff0c;主要用于全量数据备份恢复&#xff0c;也可对整个数据库中的WAL归档日志和运行日志进行备份。openGauss提供了三种物理备份与恢复相关的工具&#xff1a;gs_backup、gs_basebackup和gs_probackup。三个工具的对比见下图。…

基于FPGA的时间数字转换(TDC)设计(二)

1、多相位TDC计时FPGA代码设计 接上期的讲解,本期主要讲多相位TDC计时的FPGA代码实现。图1为TDC测量实现系统图。时间信号经过探测器后,转换为电信号,一般探测器出来的信号幅度和脉宽都比较小,需要时间鉴别器进行比较和整形,以便于FPGA能够识别。经过FPGA TDC计时模块后,…

RabbitMQ:订阅模型-消息订阅模式

订阅模型-消息订阅模式&#xff0c;也可以称为广播模式&#xff0c;生产者将消息发送到 Exchange&#xff0c;Exchange 再转发到与之绑定的 Queue中&#xff0c;每个消费者再到自己的 Queue 中取消息。 RabbitMQ 单生产单消费模型主要有以下五个角色构成&#xff1a; 生产者&am…

机器学习10大经典算法详解

“数据算法模型”。 面对具体的问题&#xff0c;选择切合问题的模型进行求解十分重要。有经验的数据科学家根据日常算法的积累&#xff0c;往往能在最短时间内选择更适合该问题的算法&#xff0c;因此构建的模型往往更准确高效。本文归纳了机器学习的10大算法&#xff0c;并分别…

Python基础语法(一)

Python基础语法 文章目录Python基础语法基础语法变量的语法(1) 定义变量(2) 使用变量变量的类型(1) 整数(2) 浮点数(小数)(3) 字符串(4) 布尔(5) 其他动态类型特性输入输出注释通过控制台输出通过控制台输入运算符算术运算符关于除法// 取整除法关系运算符逻辑运算符关于短路求…

美格智能Cat.1无线POS终端解决方案,引领消费支付新场景

近年来&#xff0c;随着我国移动互联网的蓬勃发展和智能手机的快速渗透&#xff0c;移动支付在我国全面普及。尤其是后疫情时代下&#xff0c;无接触观念的普及&#xff0c;使我国消费市场形成了以移动支付为主的消费习惯&#xff0c;并催生了万千移动支付场景终端的数字化、智…

磁盘被写保护怎么办?5个方案解除它

硬盘、移动硬盘、U盘、SD卡和TF卡&#xff08;也称为手机存储卡&#xff09;具有写保护功能。当它们出现写保护的状态&#xff0c;我们就没有办法在里面写入数据。具体而言&#xff0c;就是无法保存和删除文件。磁盘被写保护怎么办&#xff1f;你需要下面5个方案帮助你&#xf…

20221227英语学习

今日短文 How to Become an Expert 想成为行业的专家&#xff1f;不是只花时间就够了 The drive to become expert – to become as good as we can be, at whatever we’ve chosen to do – is something we all share.It is not about external markers of success.It’s a…