【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

news2024/9/26 1:27:07

在这里插入图片描述

阅读导航

  • 引言
  • 一、特殊类 --- 不能被拷贝的类
    • 1. C++98方式:
    • 2. C++11方式:
  • 二、特殊类 --- 只能在堆上创建对象的类
  • 三、特殊类 --- 只能在栈上创建对象的类
  • 四、特殊类 --- 不能被继承的类
    • 1. C++98方式
    • 2. C++11方法
  • 总结
  • 温馨提示

引言

在面向对象编程中,特殊类是指具有不同于常规类的特殊属性或限制的类。这些类可以通过各种方式达到特定的目标和需求,例如只能在堆 ( 栈 ) 上创建对象的类、禁止拷贝和继承等。

本文将会讨论四种常见的特殊类:不能被拷贝的类、只能在堆上创建对象的类、只能在栈上创建对象的类以及不能被继承的类。我们将介绍它们的实现方法和应用场景,并提供相应的代码示例以帮助读者更好地理解这些特殊类的概念和用法。

一、特殊类 — 不能被拷贝的类

当一个类的拷贝是不允许的,可以采取以下两种方式来实现:

1. C++98方式:

在C++98中,可以通过将拷贝构造函数和赋值运算符重载声明为私有,并且不实现它们来禁止拷贝。这样做的原因是私有访问权限限制了类外部的代码无法访问这两个函数的实现

class CopyBan {
private:
    CopyBan(const CopyBan&); // 声明拷贝构造函数为私有
    CopyBan& operator=(const CopyBan&); // 声明赋值运算符重载为私有
public:
    // 其他公共成员函数和数据成员
};

这种方式通过将拷贝构造函数和赋值运算符重载放在私有区域,从而阻止了类的外部对象调用这两个函数,实现了禁止拷贝的目的。

2. C++11方式:

在C++11中,可以使用delete关键字来删除拷贝构造函数和赋值运算符重载。通过在函数声明后加上= delete,可以明确告诉编译器要删除此函数,防止类外部的代码调用它

class CopyBan {
public:
    CopyBan(const CopyBan&) = delete; // 删除拷贝构造函数
    CopyBan& operator=(const CopyBan&) = delete; // 删除赋值运算符重载
    // 其他公共成员函数和数据成员
};

这种方式更加简洁明了,直观地表达了禁止拷贝的意图。使用= delete语法可以方便地阻止拷贝构造函数和赋值运算符重载的调用。

无论是C++98还是C++11,这两种方式都能有效地禁止类的拷贝,增强代码的稳定性和安全性。选择哪种方式取决于你使用的C++版本和个人偏好。

二、特殊类 — 只能在堆上创建对象的类

要设计一个只能在堆上创建对象的类,可以使用私有的析构函数和静态成员函数来实现:

class HeapOnly {
private:
    HeapOnly() {} // 私有的默认构造函数,防止在栈上创建对象
    ~HeapOnly() {} // 私有的析构函数,防止在栈上销毁对象

public:
    static HeapOnly* createInstance() {
        return new HeapOnly();
    }

    void destroyInstance() {
        delete this;
    }
};

这个类中,私有的默认构造函数和析构函数阻止了在栈上创建和销毁对象。而通过静态的createInstance()函数,可以在堆上创建该类的对象,并返回指向该对象的指针。然后,我们可以使用对象的destroyInstance()函数在适当的时候手动删除对象,从而释放内存

以下是示例代码的使用方式:

int main() {
    HeapOnly* obj = HeapOnly::createInstance();

    // 使用对象

    obj->destroyInstance();

    return 0;
}

🚨🚨注意:在这种设计中,由于析构函数是私有的,不能直接使用delete操作符来销毁对象。只能通过调用对象的destroyInstance()函数来手动删除对象

三、特殊类 — 只能在栈上创建对象的类

要设计一个只能在栈上创建对象的类,可以使用私有的构造函数和公有的静态成员函数来实现:

class StackOnly {
public:
    static StackOnly createInstance() {
        return StackOnly{};
    }

private:
    StackOnly() = default; // 私有的默认构造函数,防止在堆上创建对象
    ~StackOnly() = default; // 默认析构函数
};

这个类中,私有的构造函数阻止了在堆上创建对象。而通过公有的静态createInstance()函数,可以在栈上创建该类的对象,并返回该对象的副本由于没有指针和动态内存分配,对象的生命周期由对象所在的作用域控制,当对象离开作用域时,会自动调用析构函数销毁对象

以下是示例代码的使用方式:

int main() {
    StackOnly obj = StackOnly::createInstance();

    // 使用对象

    return 0;
}

这样设计的类限制了对象只能在栈上创建,可以避免使用者误用动态内存分配,从而提高了代码的健壮性。但请注意,在这种设计中,对象的拷贝构造函数、赋值运算符重载函数需要适当处理,以确保对象的正确复制行为。

四、特殊类 — 不能被继承的类

1. C++98方式

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

🚨🚨注意:在C++98中,虽然可以将构造函数私有化以阻止派生类调用基类的构造函数,但这并不能完全阻止继承。派生类仍然可以继承基类的成员函数和非私有成员变量

2. C++11方法

要设计一个不能被继承的类,可以使用C++中的关键字final来实现:

class NonInheritable final {
    // 类的定义
};

通过在类的声明中添加final关键字,可以阻止其他类继承该类。这样设计的类将是最终类,不能被其他类所继承。

以下是示例代码的使用方式:

class Derived : public NonInheritable { // 编译错误,无法继承NonInheritable类

};

int main() {
    NonInheritable obj; // 创建NonInheritable类的对象

    // 使用对象

    return 0;
}

这样设计的类不能被继承,可以确保类的封装性和稳定性,防止其他类对其进行修改或破坏。这在某些情况下非常有用,特别是当你希望限制类的继承性时。

总结

这些特殊类在面向对象编程中有着重要的作用,并且通过选择合适的类设计模式,我们可以更好地满足需求和解决问题。

在下一篇文章中,我们将深入研究单例模式。单例模式是一种常用的设计模式,它确保一个类只有一个实例,并提供了全局访问点。当我们需要确保只有一个对象来协调系统操作或管理共享资源时,单例模式非常有用。通过深入学习单例模式,我们将能够更好地理解其原理和使用方法,以及如何在实际开发中应用它。单例模式是一种非常有用的设计模式,掌握它将有助于我们编写可靠、高效的代码。让我们一起探索单例模式的精髓吧!敬请期待下一篇文章的发布!

温馨提示

感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

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

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

相关文章

【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

kubeadm部署k8s1.27.2版本高可用集群(外部etcd集群带TLS认证)

文章目录 环境软件版本服务器系统初始化etcd 证书生成etcd集群部署负载均衡器部署部署k8s集群部署网络组件FAQ 环境 控制平面节点主机的配置最少是2C2G,否则kubeadm init的时候会报错 主机名IP组件系统os128192.168.177.128etcd、kubeadm、kube-apiserver、kube-controller-m…

Vue3 pinia全解(上)

pinia是什么? 如果你学过Vue2,那么你一定使用过Vuex。我们都知道Vuex在Vue2中主要充当状态管理的角色,所谓状态管理,简单来说就是一个存储数据的地方,存放在Vuex中的数据在各个组件中都能访问到,它是Vue生…

【学术论文写作 笔记02】 鲁棒性实验写作的行文逻辑

文章目录 一、声明二、行文思路三、示例范文一范文二 一、声明 自己总结的,有问题望指正! 二、行文思路 为什么要做鲁棒性测试怎么做实验结论对结果的解释 三、示例 PPT 范文一 2022, TIM, “A Robust and Reliable Point Cloud Recognition Netw…

Java零基础学习22:static关键字

编写博客目的:本系列博客均根据B站黑马程序员系列视频学习和编写目的在于记录自己的学习点滴,方便后续回忆和查找相关知识点,不足之处恳请各位有缘的朋友指正。 一、static的初步应用场景 我们开始时不使用static直接用public赋值&#xff…

租户认证系统中心设计与实践

租⼾认证中⼼设计、需求背景 1. 由于客⼾,租⼾之间缺乏严肃的关系,导致从经营⻆度看不清客⼾对于公司产品的真实使⽤情况,对于客⼾运营也造成⼀定影响。 2. 在各个业务产品中实际存在⼀些客⼾需要完善⾃⾝资料的场景,但这些场景收…

上位机图像处理和嵌入式模块部署(c/c++ opencv)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 opencv可以运行在多个平台上面,当然windows平台也不意外。目前来说,opencv使用已经非常方便了,如果不想自己编译…

ANSYS 2023 下载安装教程,附安装包和工具,轻松安装,无套路

前言 ANSYS是一款融结构、流体、电场、磁场、声场分析于一体的大型通用有限元分析(FEA)软件,能与多数计算机辅助设计软件接口,实现数据的共享和交换,如Creo,NASTRAN、Algor、IDEAS、AutoCAD等. 准备工作 1、Win10及以上系统 2、提前准备好…

Keepalived 深度解析:高可用性的精髓及实践指南

Keepalived 深度解析:高可用性的精髓及实践指南 Keepalived 深度解析:高可用性的精髓及实践指南Keepalived 的工作原理1. VRRP 协议概述2. Keepalived 的角色3. VRRP 协议详解 Keepalived 的使用指南1. 安装 Keepalived使用 Yum 安装本地安装方式 2. 配置…

电商系统设计到开发03 引入Kafka异步削峰

一、前言 系统设计:电商系统设计到开发01 第一版设计到编码-CSDN博客 接着上篇文章:电商系统设计到开发02 单机性能压测-CSDN博客 本篇为大制作,内容有点多,也比较干货,希望可以耐心看看 已经开发的代码&#xff0…

基于Python的全国主要城市天气数据可视化大屏系统

1 绪论 1.1 研究的目的与意义 近年来,气候变化引发全球范围内的关注。天气数据的采集和分析对于气候预测、生态环境保护等方面都起着至关重要的作用。同时,随着科技的不断发展,数据可视化已经成为了许多领域中不可或缺的一部分。基于此&…

外包干了9个月,技术退步明显.......

先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

解决 github.com port 443: Timed out 的问题

国内访问github.com总是那么不竟如人意,时而无法加载网页,时而等我们抽完了一根烟后,它还处于转圈的状态。 虽然国内有gitee.com等诸多的代码托管平台,但却鲜有国人愿意去呢?其中的缘由,想必也不用我多说&a…

机器学习 | 利用Pandas进入高级数据分析领域

目录 初识Pandas Pandas数据结构 基本数据操作 DataFrame运算 文件读取与存储 高级数据处理 初识Pandas Pandas是2008年WesMcKinney开发出的库,专门用于数据挖掘的开源python库,以Numpy为基础,借力Numpy模块在计算方面性能高的优势&am…

system_server进程创建流程

system_server 进程是 Zygote 进程 fork 出的第一个进程,它负责管理和启动整个 Framework 层,下面附上android系统启动流程图: 记得上一篇Zygote进程创建里面提到过,forckSystemServer创建system_server进程。 /frameworks/base/…

nginx负载均衡-轮询

实验使用ubuntu做主机 1.安装nginx 安装依赖 sudo apt install libgd-dev 下载nginx wget http://nginx.org/download/nginx-1.22.1.tar.gz 解压nginx tar -zvxf nginx-1.22.1.tar.gz 编译安装 cd nginx-1.22.1 编译并指定安装位置,执行安装之后会创建指定…

鸿蒙APP的应用场景

鸿蒙APP可以用于多种场合和设备类型,这是鸿蒙系统的分布式能力和多终端适配的优势。以下是一些鸿蒙APP的应用场景,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.智能手机和平板电脑&am…

【听力与言语医学中心系列科普16】听力检查之纯音听阈测定

当我们去医院向医生诉说我们耳朵有问题时,最常听到医生说的是“去做个测听”吧,那么什么是测听?做测听有什么作用呢? 一、什么是纯音测听纯音听力测试自1943年Bunch教授发表后,就被作为首选的测听方法。纯音测听是测试…

一键轻松,免费创造:QuickQR带你体验AI二维码的轻松生成!

当今时代,将信息快速转变为可扫描图案,以简化人们的生活和工作方式,二维码技术展现了它强大的功能。特别是在分享链接、联系信息或进行支付时,二维码已成为现代社会一个不可或缺的部分。本文将探讨生成AI二维码的一种工具&#xf…

Linux服务器配置与管理(第三次实验)

实验目的及具体要求 目的 1.熟悉Shell 脚本语法 2.掌握创建脚本的方法 3.掌握运行脚本的方法 4.掌握变量及表达式 5.掌握Shell 控制结构 6.掌握Shell 函数 任务 1.显示当前日期时间、执行路径、用户账户及所在的目录位置 2.判断一个文件是不是字符设备文件&#xff0…