C++ 特殊的类设计

 目录

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

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

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

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

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


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

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

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

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. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class HeapOnly
{

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

private:
    HeapOnly() {}
      // C++98
       // 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要
        // 2.声明成私有
        HeapOnly(const HeapOnly &);

        // or c++ 11
        HeapOnly(const HeapOnly &)=delete;
};

int main()
{




    

    system("pause");
    return 0;
}

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

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

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class HeapOnly
{

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

private:
    HeapOnly() {}
//       // C++98
//        // 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要
//         // 2.声明成私有
//         // HeapOnly(const HeapOnly &);

        // or 
        HeapOnly(const HeapOnly &)=delete;
};

class StackOnly{

    public:
        static StackOnly CreateObj(){
            return StackOnly();
        }

        // 禁用掉operator new 可以把new 调用拷贝申请对象给禁掉
//  void 是C++中的一种特殊类型,表示一个指向未知类型的指针。它可以用来表示任意类型的指针,因为在C++中,所有的指针类型都可以隐式地转换为void类型。
// void *通常用于在不确定指针类型的情况下进行内存分配和传递。
// 在你提到的代码中,void * operator new(size_t size) = delete;
// 是一个重载的new操作符函数,它的作用是禁止使用该函数进行内存分配。通过将其定义为delete,可以阻止使用该操作符进行内存分配,从而达到限制内存分配的目的。
// 需要注意的是,void *类型的指针在使用时需要进行类型转换才能使用,因为它没有指定具体的类型。在使用void *指针时,需要谨慎处理类型转换,以避免出现错误

        void *operator new(size_t size)=delete;
        void operator delete(void *p)=delete;


    private:

        StackOnly():_a(0){}

        int _a;

};

int main()
{

    void * a=new int(2);
    cout<<a<<endl;




    system("pause");
    return 0;
}

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

        C++98方式

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;



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

    private:
        NonInherit(){

        }

};





int main()
{





system("pause");
return 0;
}

C++11方法 final关键字,fifinal修饰类,表示该类不能被继承。

        

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;



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

    private:
        NonInherit(){

        }

};

class A final{



};




int main()
{





system("pause");
return 0;
}

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

        

设计模式:

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的

总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打

仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后

来孙子就总结出了《孙子兵法》。孙子兵法也是类似。

使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模

式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

单例模式:

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个

访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置

信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再 通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

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

饿汉模式

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

// 饿汉模式

// 优点:简单

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

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;


class Singleton{

    public:
        static Singleton *GetInstance(){
            return &m_instance;
        }


    private:
        Singleton(){}

        //c++ 98 防止拷贝
        // Singleton(Singleton const &);
        // Singleton& operator=(Singleton const &);

        //c++ 11 防止拷贝
        Singleton(Singleton const &)=delete;
        Singleton& operator=(Singleton const &)=delete;

        static Singleton m_instance;

};

Singleton Singleton::m_instance;//在程序入口之前就完成初始化



int main()
{





system("pause");
return 0;
}

如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避

免资源竞争,提高响应速度更好.

        

  • 懒汉模式

如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取

文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,

就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好.

// 懒汉

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

// 缺点:复杂

#include<iostream>
#include<vector>
#include<mutex>
#include<thread>
#include<algorithm>
using namespace std;

//饿汉式

// class Singleton{

//     public:
//         static Singleton *GetInstance(){
//             return &m_instance;
//         }

//     private:
//         Singleton(){}

//         //c++ 98 防止拷贝
//         // Singleton(Singleton const &);
//         // Singleton& operator=(Singleton const &);

//         //c++ 11 防止拷贝
//         Singleton(Singleton const &)=delete;
//         Singleton& operator=(Singleton const &)=delete;

//         static Singleton m_instance;

// };

// Singleton Singleton::GetInstance();//在程序入口之前就完成初始化

//懒汉式
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 &)=delete;
    Singleton &operator=( Singleton const&)=delete;

    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;

system("pause");
return 0;
}

运行结果:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何转行成为产品经理?

转行NPDP也是很合适的一条发展路径&#xff0c;之后从事新产品开发相关工作~ 一、什么是NPDP&#xff1f; NPDP 是产品经理国际资格认证&#xff0c;美国产品开发与管理协会&#xff08;PDMA&#xff09;发起的&#xff0c;是目前国际公认的唯一的新产品开发专业认证&#xff…

学术神器ChatGPT在论文分析中的妙用!

话语分析是一个广泛的研究领域&#xff0c;它关注的是人们在实际社会交际场景中使用的语言单位。话语分析旨在揭示语言、社会和文化之间的互动关系&#xff0c;以及话诺在构建意义、传递信息、维护社会关系和表达权力等方面的作用。话语分析包括对话分析、批判性话语分析、语篇…

AI安全白皮书 | “深度伪造”产业链调查以及四类防御措施

以下内容&#xff0c;摘编自顶象防御云业务安全情报中心正在制作的《“深度伪造”视频识别与防御白皮书》&#xff0c;对“深度伪造”感兴趣的网友&#xff0c;可在文章留言中写下邮箱&#xff0c;在该白皮书完成后&#xff0c;会为您免费寄送一份电子版。 “深度伪造”就是创建…

基于亚马逊云科技新功能:Amazon SageMaker Canvas 无代码机器学习—以构建货物的交付状态检测模型实战为例深度剖析以突显其特性

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 亚马逊云科技 2023 re:Invent 全球大会是亚马逊云科技举办的一场技术盛会&#xff0c;…

基于FPGA的PSRAM接口设计与实现

一 PSRAM与HyperRAM 1、概述 2、异同 待完善 二 PSRAM分析 1、特性 1、关键点 待完善 三 PSRAM方案设计与验证 待完善 1、整体方案设计 2、验证 仿真工具采用VCSVerdi&#xff0c;PSRAM接口控制IPAPS6408L model进行验证。 四 结论 备注&#xff1a;以AP公司的APS6408L…

深入理解与应用Keepalive机制

目录 引言 一、VRRP协议 &#xff08;一&#xff09;VRRP概述 1.诞生背景 2.基本理论 &#xff08;二&#xff09;VRRP工作原理 &#xff08;三&#xff09;VRRP相关术语 二、keepalive基本理论 &#xff08;一&#xff09;基本性能 &#xff08;二&#xff09;实现原…

异地组网需要几个固定IP?

异地组网指的是在不同地区的终端设备之间建立起稳定的网络连接&#xff0c;以实现信息的远程传输和通信。在进行异地组网时&#xff0c;需要固定IP地址来确保网络连接的稳定性和可靠性。本文将介绍异地组网的基本概念和必要性&#xff0c;并探讨在这一过程中需要使用的固定IP的…

16-Java命令模式 ( Command Pattern )

Java命令模式 摘要实现范例 命令模式&#xff08;Command Pattern&#xff09;中请求以命令的形式包裹在对象中&#xff0c;并传给调用对象 调用对象寻找可以处理该命令的合适的对象&#xff0c;并把该命令传给相应的对象&#xff0c;该对象执行命令 命令模式是行为型模式&…

接收端编程、UDP编程练习、wireshrak抓包工具、UDP包头

我要成为嵌入式高手之3月6日Linux高编第十六天&#xff01;&#xff01; ———————————————————————————— 学习笔记 接收端 recvfrom #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, si…

java SSM流浪宠物救助与领养myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM流浪宠物救助与领养管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系…

Python 过滤函数filter()详解

一、过滤函数定义 它用于对容器中的元素进行过滤处理。 二、 过滤函数语法 filter(function,iterable) 参数function&#xff1a;提供过滤条件的函数&#xff0c;返回布尔型 参数iterable: 容器类型数据 三、过滤函数的应用场景 1、筛选符合条件的元素 需求&#xff1a;在列表…

【MySQL】not in遇上null的坑

今天遇到一个问题&#xff1a; 1、当 in 内的字段包含 null 的时候&#xff0c;正常过滤&#xff1b; 2、当 not in 内的字段包含 null 的时候&#xff0c;不能正常过滤&#xff0c;即使满足条件&#xff0c;最终结果也为 空。 测试如下&#xff1a; select * from emp e;当…

根据标签出现的频次渲染不同大小的圆和文字,圆随机摆放且相互之间不重叠

效果图&#xff1a; 按每个标签出现的频次大小渲染出不同比例大小的圆&#xff0c;渲染的圆的宽度区间为 [40, 160] &#xff0c;其中的文字的大小区间为 [12, 30] &#xff0c;圆的位置随机摆放且不重叠。 根据已知条件可得出&#xff0c;标签中频次最高的对应圆的宽度(直径…

【网络】:再谈传输层(UDP)

传输层 一.再谈端口号二.UDP 一.再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序。 在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信(可以通过netstat -n查看); 1.端口号划分 0 - 1023:…

第5章 HSA内存模型

5.1 引言 在共享内存环境中&#xff0c;独立的控制线程可以竞相修改单个位置。为程序以可预测的方式运行&#xff0c;程序员必须用同步来控制这些竞争。 “内存一致性模型”或“内存模型”定义了并行代理之间通信的基本规则。当这些规则含糊不清地定义或者更糟的是完全不存在…

简站wordpress主题看上去差不多 实际大不一样

有人说简站wordpress主题&#xff0c;都差不多嘛。我表示无语。表面看上去是差不多的&#xff0c;实际的细节是不一样的。 下面以编号&#xff1a;JZP4431和编号&#xff1a;JZP4878这两个主题为例子来讲一下&#xff0c;简站wordpress主题&#xff0c;在细节方面的不一样之处…

Tensorflow实现手写数字识别

模型架构 具有10个神经元&#xff0c;对应10个类别&#xff08;0-9的数字&#xff09;。使用softmax激活函数&#xff0c;对多分类问题进行概率归一化。输出层 (Dense):具有64个神经元。激活函数为ReLU。全连接层 (Dense):将二维数据展平成一维&#xff0c;为全连接层做准备。展…

智能部署之巅:Amazon SageMaker 引领机器学习革新

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 &#xff08;全球 TMT 2023年12月6日讯&#xff09;亚马逊云科技在 2023 re:Invent 全…

vue element plus Upload 上传

通过点击或者拖拽上传文件。 基础用法# 通过 slot 你可以传入自定义的上传按钮类型和文字提示。 可通过设置 limit 和 on-exceed 来限制上传文件的个数和定义超出限制时的行为。 可通过设置 before-remove 来阻止文件移除操作。 Click to upload jpg/png files with a size …

python--宣传篇--personal-qrcode个性二维码

文章目录 准备代码效果 准备 代码 from MyQR import myqr import osdef get_img_qrcode(words, save_name, picture, colorizedTrue):if save_name[-3:] in ["jpg", "png", "gif"]:if picture[-3:] in ["png", "jpg", &qu…