【C++高阶】解锁C++的深层魅力——探索特殊类的奥秘

📝个人主页🌹:Eternity._
⏩收录专栏⏪:C++ “ 登神长阶 ”
🤡往期回顾🤡:C++ 类型转换
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

❀C++特殊类

  • 📒1. 不能被拷贝的类
  • 📙2. 只能在堆上创建对象
  • 📚3. 只能在栈上创建对象
  • 📜4. 不能被继承的类
  • 📝5. 只能创建一个对象(单例模式)
    • 🌞设计模式
    • ⭐单例模式
  • 📖6. 总结


前言:在C++这片浩瀚的编程海洋中,基础语法与常用库如同岛屿与浅滩,引领着每一位初学者逐步前行。然而,当我们的航程逐渐深入,便会发现那些隐藏于波涛之下的特殊类,它们如同深海中的宝藏,等待着勇敢的探索者去发掘

特殊类,作为C++语言中的高级特性之一,不仅承载着对面向对象编程思想的深刻体现,更是解决复杂问题、优化程序性能的利器。它们包括但不限于模板类、智能指针、迭代器、多态基类(抽象类)、以及那些利用高级特性(如RAII、类型萃取等)设计的独特类。这些特殊类以其独特的设计理念和强大的功能,在C++的各个领域发挥着不可替代的作用

现在我将带领大家一同踏上这场探索之旅,通过详细解析C++中的特殊类,揭示它们的设计原理、应用场景以及使用技巧。我们将从基础概念出发,逐步深入到高级特性,通过实例演示和代码分析,帮助读者逐步掌握这些特殊类的精髓

让我们一同揭开C++特殊类的神秘面纱,领略其独特的魅力与力量吧!


📒1. 不能被拷贝的类

拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载

实现方式:

因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可

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

原因:

  • 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就可以不
    能禁止拷贝了
  • 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写
    反而还简单,而且如果定义了就不会防止成员函数内部拷贝了
  • C++11:C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数

代码示例 (C++):

//不能被拷贝的类
//C++98
class CopyBan
{// ...
private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//...
};//C++11
class CopyBan
{// ...CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;//...
};

📙2. 只能在堆上创建对象

实现方式:

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


方案一:析构函数私有化:

正常创建对象,会自动调用析构函数,将析构函数私有化,外部代码将无法直接调用delete来销毁对象,因为这将尝试访问一个不可访问的析构函数,要想销毁对象就得自己定义成员函数来操作

代码示例 (C++):

//只能在堆上创建对象
class HeapOnly
{
public:// 对象的销毁/*static void Destroy(HeapOnly* ptr){delete ptr;}*/// 对象的销毁void Destroy(){delete this;}private:~HeapOnly(){cout << "~HeapOnly()" << endl;}
};int main()
{HeapOnly* ptr = new HeapOnly;//HeapOnly::Destroy(ptr);ptr->Destroy();return 0;
}

方案二:构造函数私有化:

通过将构造函数私有化,我们可以限制对象创建的方式,从而实现只能在堆上创建对象

代码示例 (C++):

class HeapOnly
{
public:// 静态的成员函数,完成完成堆对象的创建static HeapOnly* CreateObj(){return new HeapOnly;}private:HeapOnly(){cout << "HeapOnly()" << endl;}// 防止别人调用拷贝在栈上生成对象//C++98HeapOnly(const HeapOnly& copy);//C++11HeapOnly(const HeapOnly& copy) = delete;
};int main()
{HeapOnly* ptr = HeapOnly::CreateObj();//HeapOnly copy(*ptr);return 0; 
}

📚3. 只能在栈上创建对象

实现方式:

将类的构造函数私有,提供一个静态的成员函数,在该静态成员函数中完成栈对象的创建

思考一下:这里的实现方法和上面似乎有点相同,但是我们在实现时,是否也要像上面一样delete掉拷贝构造呢?

静态成员函数 -> 完成栈对象的创建:

static StackOnly CreateObj(){StackOnly obj;return obj;}
// 这里会让对象在堆上创建
StackOnly* ptr = new StackOnly(obj);
// 如果我们 delete 拷贝构造,会发现CreateObj()也会受到影响,所以我们只能另辟蹊径
// 我们要从 new 下手让我们不能用 new 来创建对象

实现专属的operator new

void* operator new(size_t size)
{cout << "void* operator new(size_t size)" << endl;return malloc(size);
}

当我们new这类对象时,我们会优先调用operator new,而不是全局(就近原则),因此我们delete掉我们自己实现的operator new,我们就不能在使用new创建对象

代码示例 (C++):

// 只能在栈上创建的类
class StackOnly
{
public:static StackOnly CreateObj(){StackOnly obj;return obj;}// 如果我们将拷贝构造delete,那么我们就无法创建对象,因为在CreateObj()中也会发生拷贝构造//StackOnly(const StackOnly& copy) = delete;void* operator new(size_t size) = delete;//实现专属的operator new//当我们new这类对象时,我们会优先调用operator new,而不是全局(就近原则)/*void* operator new(size_t size){cout << "void* operator new(size_t size)" << endl;return malloc(size);}*/private:StackOnly(){cout << "StackOnly()" << endl;}
};int main()
{StackOnly obj = StackOnly::CreateObj();// 发生拷贝构造是会在堆上创建类,但是我们能不能将拷贝构造delete呢?//StackOnly* ptr = new StackOnly(obj);return 0;
}

📜4. 不能被继承的类

实现方式:

  • C++98:中构造函数私有化,派生类中调不到基类的构造函数就无法继承

  • C++11:一个类如果不希望被其他类继承,可以通过将其声明为final类来实现

代码示例 (C++):

// 不能被继承的类
//C++98
class A
{
public:static A GetInstance(){return A();}
private:A(){}
};// 不能被继承的类
//C++11
class A final
{// ....
};

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

🌞设计模式

设计模式(Design Patterns)是一种在软件开发中用于解决常见问题的可重用的解决方案。它们不是代码本身,而是关于如何组织代码和对象之间关系的一种描述和指导,是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结

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

设计模式是面向对象设计原则的体现,它们通过提供可重用的解决方案来帮助开发者更好地设计和实现软件系统。在实际开发中,可以根据具体的需求和场景选择合适的设计模式来解决问题


⭐单例模式

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

单例模式的核心在于控制实例的数目,节省系统资源,并允许全局访问

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

  • 饿汉模式
  • 懒汉模式

  • 饿汉模式
    提前创建好程序,启动时就创建一个唯一的实例对象 -> (提前做好)

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

代码示例 (C++):

class A
{
public:static A* GetInstance(){return &_inst;}void Add(const string& key, const string& value){_dict[key] = value;}void Print(){for (auto& kv : _dict){cout << kv.first << ":" << kv.second << endl;}}private:A() // 私有构造函数  {}//限制类外随意创建对象A(const A& copy) = delete;A& operator=(const A& aa) = delete;map<string, string> dict;static A _inst;// 静态实例  };
// 类的外部定义静态实例  
A A::_inst;int main()
{A::GetInstance()->Add("sort", "排序");A::GetInstance()->Add("left", "左边");A::GetInstance()->Add("right", "右边");A::GetInstance()->Print();return 0;
}
  • 懒汉模式
    第一次用的时候在创建 -> (现吃现做)

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

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

注意:new的懒汉对象一般不需要释放,进程正常结束会释放资源

代码示例 (C++):

class B
{
public:static B* GetInstance(){// 第一次为空的时候,创建对象if (_inst == nullptr){_inst = new B;}return _inst;}void Add(const string& key, const string& value){_dict[key] = value;}void Print(){for (auto& kv : _dict){cout << kv.first << ":" << kv.second << endl;}}static void DelInstance(){if (_inst){delete _inst;_inst = nullptr;}}
private:B(){}//限制类外随意创建对象B(const B& copy) = delete;B& operator=(const B& bb) = delete;map<string, string> _dict;static B* _inst; // 指针的形式class gc{public:~gc(){DelInstance();}};static gc _gc;
};B* B::_inst = nullptr;
B::gc B::_gc;int main()
{B::GetInstance()->Add("sort", "排序");B::GetInstance()->Add("left", "左边");B::GetInstance()->Add("right", "右边");B::GetInstance()->Print();return 0;
}

懒汉模式并非这么简单,后面还要牵扯到线程安全,线程安全需要额外处理


📖6. 总结

随着我们一同探索了C++中特殊类的广阔天地,相信你已经对这些高级特性有了更深的理解与感悟。特殊类不仅是C++语言复杂性和强大功能的体现,更是编程艺术的结晶,它们以独特的方式解决了传统编程中难以处理的问题,提升了代码的效率、安全性和可维护性

学习特殊类的过程,实际上是一个不断挑战自我、深化编程思维的过程。它要求我们不仅要掌握语法层面的知识,更要理解其背后的设计思想和实现原理。只有这样,我们才能真正驾驭这些特殊类,将它们灵活地应用于实际开发中,解决实际问题

用一句话总结一下就是:“掌握C++特殊类,就是掌握了一种强大的编程工具,它将助你在编程的世界里走得更远、更稳。”
愿你在未来的编程道路上,能够勇往直前、不断突破自我,创造出更多优秀的作品和成果!

在这里插入图片描述

希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!

在这里插入图片描述

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

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

相关文章

文字loading加载

效果 1. 导入库 import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal from PyQt5.QtGui import QPainter, QFont, QColor, QBrush from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QProgressBar, QLabel 代码首先导入了P…

C++ | Leetcode C++题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindrome(string s) {unordered_map<char, int> count;int ans 0;for (char c : s)count[c];for (auto p : count) {int v p.second;ans v / 2 * 2;if (v % 2 1 and ans % 2 0)ans;}retur…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…

macOS上谷歌浏览器的十大隐藏功能

谷歌浏览器&#xff08;Google Chrome&#xff09;在macOS上拥有一系列强大而隐蔽的特性&#xff0c;这些功能能显著提高您的浏览体验。从多设备同步到提升安全性和效率&#xff0c;这些被低估的功能等待着被发掘。我们将逐步探索这些功能&#xff0c;帮助您最大化利用谷歌浏览…

力扣题解815

大家好&#xff0c;欢迎来到无限大的频道。祝大家中秋节快乐​。 今日继续给大家带来力扣题解。 题目描述&#xff08;困难&#xff09;​&#xff1a; 公交路线 给你一个数组 routes &#xff0c;表示一系列公交线路&#xff0c;其中每个 routes[i] 表示一条公交线路&…

Python logging库(python日志库)Logger(记录器、收集器、采集器)、Handler(处理器)、Formatter(格式化器)、Log Level(日志级别)

文章目录 Python Logging库详解简介日志记录的基本概念1. Logger&#xff08;记录器&#xff09;&#xff1a;这是日志系统的入口点。每个记录器都有一个名称&#xff0c;并且记录器之间可以存在父子关系。2. Handler&#xff08;处理器&#xff09;&#xff1a;记录器将日志消…

网络安全-intigriti-0422-XSS-Challenge Write-up

目录 一、环境 二、解题 2.1看源码 一、环境 Intigriti April Challenge 二、解题 要求&#xff1a;弹出域名就算成功 2.1看源码 我们看到marge方法&#xff0c;肯定是原型链污染题目 接的是传参&#xff0c;我们可控的点在于qs.config和qs.settings&#xff0c;这两个可…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) 接口隔离原则&#xff1a;Interface Segregation Principle&#xff0c;简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法&#xff1b;一个类对另一个类的依赖应该建立在最小的接…

Invoke-Maldaptive:一款针对LDAP SearchFilter的安全分析工具

关于Invoke-Maldaptive MaLDAPtive 是一款针对LDAP SearchFilter的安全分析工具&#xff0c;旨在用于对LDAP SearchFilter 执行安全解析、混淆、反混淆和安全检测。 其基础是 100% 定制的 C# LDAP 解析器&#xff0c;该解析器处理标记化和语法树解析以及众多自定义属性&#x…

Excel图片批量插入单元格排版处理插件【图片大师】

为了方便大家在图片的插入排版的重复工作中解放出来&#xff0c;最近发布了一款批量插入图片的插件&#xff0c;欢迎大家下载&#xff0c;免费试用。 这是图片的文件夹&#xff1a; 主要功能如下: 1&#xff0c;匹配单元格名称的多张图批量插入到一个单元格 该功能支持设置图…

腾讯百度阿里华为常见算法面试题TOP100(4):双指针、哈希、滑动窗口

之前总结过字节跳动TOP50算法面试题&#xff1a; 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 目录 双指针 42.接雨水 283.移动零 11.盛最多水的容器 15.三数之和 哈希 1. 两数之和 49.字母异位词分组 128.最长连续序列 滑动窗…

网络协议全景:Linux环境下的TCP/IP、UDP

目录 1.UDP协议解析1.1.定义1.2.UDP报头1.3.特点1.4.缓冲区 2.TCP协议解析2.1.定义2.2.报头解析2.2.1.首部长度&#xff08;4位&#xff09;2.2.2.窗口大小2.2.3.确认应答机制2.2.4.6个标志位 2.3.超时重传机制2.4.三次握手四次挥手2.4.1.全/半连接队列2.4.2.listen2.4.3.TIME_…

SQL进阶的技巧:如何实现某列的累计乘积?

目录 0 场景描述 1 数据准备 2 问题分析 3 完全情况查询 4 小结 0 场景描述 在做数据处理的时候,尤其是复利累积的时候,有时候会有这样一场景,通过某种条件找到一列数据[X1,X2,X3...Xn],然后想要求y=X1X2X3...Xn。下面给出一个具体案例来详细解释这一问题,如下图所示…

学成在线练习(HTML+CSS)

准备工作 项目目录 内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等 1.由于元素具有一些默认样式&#xff0c;可能是我们写网页过程中根本不需要的&#xff0c;所有我们可以在写代码之前就将其清除 base.css /* 基础公共样式&#xff1a;清除…

大模型入门3:理解LLAMA

LLama在transformers库中的代码&#xff0c;以及各部分原理Llama3.1技术报告LLama 33b 微调尝试 Model a stack of DecoderBlocks(SelfAttention, FeedForward, and RMSNorm) decoder block 整体结构&#xff1a;最大的区别在pre-norm x -> norm(x) -> attention() -…

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源&#xff0c;作用&#xff1a;1.使IO口的不确定电平稳定在高点平&#xff0c;2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连&#xff0c;作用&#xff1a;1.从器件输出电流 2.当IO口为输入状态时&#xff0c;引脚的…

【爱给网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

Flet全平台开发:软件开发界勇士为Python语言补短板的一次极具挑战性的尝试、冲刺和华丽亮相

一、Flet创始人和开发者介绍、开发Flet的背景介绍 Flet 的创始人和开发者 Feodor Fitsner 是俄罗斯人&#xff0c;就职于微软。 Flet 的第一个版本于 2022 年 6 月发布。这是一个相对较新的库&#xff0c;它基于 Flutter 框架&#xff0c;首先支持的是用 Python 语言开发软件…

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一&#xff0c;地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址&#xff0c;把整个机器内存比作一个酒店&#xff0c;内存单元就是这个酒店的各个房间&#xff0c;给这些房间编的门牌号&#xff0c;类比回来就是内存单元的物理地址 在第一篇介绍debug的…

文心智能体应用:美国旅游助手的诞生

创造灵感 在如今的数字化时代&#xff0c;旅行体验越来越依赖于智能技术的辅助。从机票预订到行程安排&#xff0c;再到当地美食推荐&#xff0c;智能助手在旅行中的作用愈发重要。尤其在美国这样一个广袤且多样化的国家&#xff0c;拥有一个智能旅行助手能够极大地提升游客的…