特殊类的设计----《Hello C++ Wrold!》(28)--(C/C++)

特殊类的设计----《Hello C++ Wrold!》(28)--(C/C++)

文章目录

前言

在 C++ 面向对象编程体系中,类是封装数据与行为的核心单元,其设计直接关系到程序的安全性、可维护性与性能表现。除了支撑常规业务逻辑的普通类,实际开发中常需面对具有特殊约束的场景:例如防止对象拷贝以规避资源重复释放风险,限定对象创建位置(仅堆或仅栈)以规范内存管理,禁止类被继承以保障核心逻辑不被篡改,或是确保类仅存在一个实例以实现全局资源统一调度 —— 这些需求的实现,正是特殊类设计的核心范畴。​

本文聚焦 “特殊类设计” 这一主题,系统拆解五种典型特殊类的实现逻辑与技术细节。从 “不能被拷贝的类” 对拷贝构造函数、赋值运算符的管控,到 “只能在堆 / 栈上创建对象的类” 对构造函数与内存分配接口的限制;从 “不能被继承的类” 基于构造函数私有化(C++98)与final关键字(C++11)的两种实现,到 “单例模式(仅一个对象的类)” 的饿汉模式与懒汉模式对比,每类设计均结合 C++ 语言特性,提供完整代码示例,并深入分析方案的优缺点与适用场景。​

无论是 C++ 学习者进阶理解类的设计边界,还是开发人员解决实际项目中的特殊类需求,本文都将通过清晰的原理讲解与实用的技术指引,助力读者掌握特殊类设计的核心思路,提升代码设计的严谨性与专业性。

设计一个不能被拷贝的类

只需让该类不能调用拷贝构造函数以及赋值运算符重载即可
C++98的方法: 将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有 C++11的方法: 用delete禁止生成拷贝构造函数和赋值运算符重载的默认成员函数 

设计一个只能在堆上创建对象的类

方法:

让这个类不能被拷贝并且构造函数设置成私有的

然后再提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建
实现举例:classHeapOnly{public:static HeapOnly*CreateObj(){returnnew HeapOnly;}private:HeapOnly(){//...}HeapOnly(const HeapOnly& hp)=delete; HeapOnly&operator=(const HeapOnly& hp)=delete;};

设计一个只能在栈上创建对象的类

方法:先把构造函数私有化 并且禁用operator new

然后再搞个静态成员函数去构造对象就行了(不搞成静态的话,没对象的时候调用不了)

–这里构造函数私有化的意义:防止外面eg: new A()这样
实现举例:classStackOnly{public:static StackOnly CreateObj(){ StackOnly st;return st;}private:StackOnly(){//...}void*operatornew(size_t size)=delete;};
引申:关于这里的operator new,这个的话默认调用的是全局的new,这类里面这样搞了之后这个类就用不了new

设计一个不能被继承的类

方法:

第一种:(C++98的方法):让构造函数私有化就行了

第二种(C++11的方法):用final关键字

设计一个只能创建一个对象的类(也叫做单例模式)

单例模式的概念:就是一个类只能创建一个对象

作用:该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

单例模式的两种实现方法

饿汉模式

这个模式的优缺点:

优点:实现起来简单

缺点:1、如果单例对象初始化内容很多,影响启动速度
2、如果两个单例类,互相有依赖关系,这时候对实例化的顺序有要求–但是饿汉模式控制不了实例化的顺序(尤其是在不同的编译单元)

namespace hungry {classSingleton{public:static Singleton&GetInstance(){return _sinst;}private:Singleton(){// ...}//这里是防拷贝,自己演示的是C++11的方式Singleton(const Singleton& s)=delete; Singleton&operator=(const Singleton& s)=delete;static Singleton _sinst;}; Singleton Singleton::_sinst;

懒汉模式

在这里插入图片描述
namespace lazy {classSingleton{public:static Singleton&GetInstance(){if(_psinst ==nullptr){ _psinst =new Singleton;}return*_psinst;}staticvoidDelInstance(){if(_psinst){delete _psinst; _psinst =nullptr;}}classtmp{public:~tmp(){ lazy::Singleton::DelInstance();}};private:Singleton(){// ...}// 防拷贝Singleton(const Singleton& s)=delete; Singleton&operator=(const Singleton& s)=delete;static Singleton* _psinst;static tmp _tmp;}; Singleton* Singleton::_psinst =nullptr;//这意味着程序启动时,单例对象并没有被创建,仅仅是定义了一个指向它的空指针。 Singleton::tmp Singleton::_tmp;}
在这里插入图片描述
一般单例不需要释放:因为程序结束的时候,操作系统会自动去回收的(用的不是析构函数)

除非特殊场景:

1.中途需要显示释放 2.程序结束时,需要做一些特殊动作(比如持久化)

这里的第二种情况的持久化就是需要在程序结束时将数据写入其他地方–这个时候就需要调用析构函数,用析构函数写入–tmp就保证了他的析构函数会起作用

Read more

【C++】类和对象—(下) 收官之战

【C++】类和对象—(下) 收官之战

前言:上一篇文章我们向大家介绍了类和对象的核心六个成员函数中的4个,其余两个以及初始化列表,static成员,内部类,匿名对象等会在本篇文章介绍! ✨ 坚持用清晰易懂的图解+代码语言, 让每个知识点都简单直观! 🚀 个人主页 :MSTcheng · ZEEKLOG 🌱 代码仓库 :MSTcheng · Gitee 📌 专栏系列 :📖 《C语言》🧩 《数据结构》💡 《C++由浅入深》💬 座右铭 :“路虽远行则将至,事虽难做则必成!” 文章目录 * 一,运算符重载 * 1.1什么是运算符重载? * 1.2 为什么要创造运算符重载? * 二,赋值运算符重载 * 2.1赋值运算符重载的构成 * 2.1 >>流插入<<流提取重载 * 3.1const成员函数 * 4.1取地址运算符重载 * 三,初始化列表 * 3.

By Ne0inhk

为什么顶尖团队都在用Concepts简化C++元编程?真相在这里

第一章:为什么顶尖团队都在用Concepts简化C++元编程? C++20 引入的 Concepts 彻底改变了模板元编程的编写方式,让类型约束从“运行时错误”转向“编译时契约”。传统模板依赖 SFINAE 或 requires 表达式进行类型检查,代码冗长且难以维护。而 Concepts 提供了一种清晰、可读性强的语法,使开发者能直接声明模板参数的语义要求。 更直观的类型约束 使用 Concepts 可以定义可重用的约束条件,提升模板接口的可读性与安全性。例如,定义一个适用于所有可加类型的操作: template concept Addable = requires(T a, T b) { { a + b } -> std::same_as; }; template T add(T a,

By Ne0inhk
【哈希表封装实现】—— 我与C++的不解之缘(二十九)

【哈希表封装实现】—— 我与C++的不解之缘(二十九)

前言 我们知道unordered_set和unordered_map的底层是哈希表,那现在我们就是使用我们自己实现的HashTable来封装实现出简单的unordered_set和unordered_map。 一、了解源码 在SGL-STL30版本之前源代码中是没有unordered_set和unordered_map的 unordered_set和unordered_map是C++11之后才更新的;SGL-STL30是C++11之前的版本 但是想SGL-STL30中实现了哈希表,但容器的名字叫做hash_map和hash_set(它是作为非标准的容器出现的) 源代码在hash_map/hash_set/stl_hash_map/stl_hash_map/stl_hash_set/stl_hashtable.h中 这里截取其中的一部分来看一下: // stl_hash_settemplate<classValue,classHashFcn= hash<Value>

By Ne0inhk
嘿嘿 解决了Dev C++ 中文乱码(有效版)

嘿嘿 解决了Dev C++ 中文乱码(有效版)

这是博主第一篇博客!记录一下博主的小小小小解决史! 很早就下载用了Dev c++ ,但现在隔了很长时间没去用过了再次打开发现出现中文乱码的现象!在网站上翻阅了许久!终于解决了问题!困扰了许久! ——————————————————————— 这个中文乱码看着是真烦得慌!!! tips:不要急不要急,事情慢慢都能解决掉滴! 还有不要保存在C盘哦!最好都保存在D盘内!本博客示范的未命名1.c 保存于C盘桌面上是为了演示方便! ———————————————————————————  图1 这是我们原来出现中文乱码的界面 编译的时候会出现这个窗口   图一 (再说一遍!这个中文乱码在之前没解决掉问题的时候一看到这个就很烦! ) 图二是编译过后(中文乱码版) 图二          ————————————————————————— 第一种方法(也是博主强推亲测有效法) ·第一步         请点击左上角<控制台界面>左上角                选中<默认值D> 图三   操作第一步     ·第二步          将下方“使用旧版本

By Ne0inhk