【C++】一些特殊类的实现


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

    //法一
    class HeapOnly
    {
    public:
    //2. 创建对象,提供接口
    //如何创建对象?写一个接口创建对象,但调用该函数需要对象,对象需要调用该函数才创建,
    //所以可以将该函数变成静态成员函数。
    static HeapOnly* CreateObj()
    {
    return new HeapOnly;
    }

    private:
    //1. 将构造函数私有化
    HeapOnly()
    {
    //......
    }

    复制代码
     //3. 防止拷贝
     HeapOnly(const HeapOnly& ho) = delete;//告诉编译器删除该函数
     HeapOnly& operator=(const HeapOnly& ho) = delete;

    };

    //法二
    class HeapOnly
    {
    public:

    复制代码
     //2. 写一个函数释放资源
     //为什么用写一个函数释放空间?HeapOnly hp1在程序结束后会调用析构函数,但析构函数已私有,
     //所以hp1创建失败;HeapOnly* hp2在程序结束后不会调用析构函数,所以得自己写一个函数手动
     //释放资源。
     void Destroy()
     {
     	//delete ......
     }

    private:
    //1. 将析构函数私有化
    ~HeapOnly()
    {
    //......
    }
    };

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

    class StackOnly
    {
    public:
    //2. 提供接口,返回对象
    static StackOnly CreateObj()
    {
    StackOnly so;
    return so;
    }

    复制代码
     //3. new = operator new + 构造(或者拷贝构造)。还有可能在堆上创建空间,
     //StackOnly* so2 = new StackOnly(so1),但我们不能将拷贝构造私有且封掉,
     //因为上面函数是传值返回,会调用拷贝构造,所以得实现一个类专属的operator
     //new,然后私有再封掉,这样就不会在堆上创建空间

    private:
    //1. 将构造函数私有
    StackOnly()
    {
    //......
    }

    复制代码
     //3. 私有operator new
     void* operator new(size_t size) = delete;

    };

  3. 请设计一个类,该类不能发生拷贝

    class CopyBin
    {
    public:
    private:
    CopyBin(const CopyBin& cb) = delete;
    CopyBin& operator=(const CopyBin& cd) = delete;
    };

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

    //法一:+final
    class NoInherit final
    {
    public:
    private:
    };

    //法二:
    class NoInherit
    {
    public:
    private:
    //将构造函数私有。子类对象构造必须调用父类的构造,不能调用就无法继承
    NoInherit()
    {
    //......
    }
    };

  5. 单例模式

    //请设计一个类,该类只能创建一个对象(即:单例模式(重要))
    //a.什么是单例模式?一个类只能创建一个对象
    //b.模拟实现饿汉模式,并给出其优缺点
    namespace hungry
    {
    class OnlyOne
    {
    public:
    //2. 提供获得单例对象的成员函数
    static OnlyOne& GetInstance()
    {
    return _ins;
    }

    复制代码
     private:
     	//1. 构造函数私有
     	OnlyOne()
     	{
     		//......
     	}
    
     	//3. 防拷贝
     	OnlyOne(const OnlyOne& oo) = delete;
     	OnlyOne operator=(const OnlyOne& oo) = delete;
    
     	static OnlyOne _ins;
     };
     OnlyOne OnlyOne::_ins;
     //优点:实现简单
     //缺点:1.如果单例对象初始化内容多,会影响启动速度。(main是启动入口,启动之前要做准备,还要创建单例对象)
     //2.如果有多个单例对象,启动顺序不确定。

    }

    //c.模拟实现懒汉模式,并给出其优缺点
    namespace lazy
    {
    class OnlyOne
    {
    public:
    //2. 提供获得单例对象的成员函数
    static OnlyOne& GetInstance()
    {
    if (_ins == nullptr)
    {
    _ins = new OnlyOne;
    }
    return *_ins;
    }

    复制代码
     	//4. 一般单例不用释放,单例一般进程结束就结束,让编译器自动回收就行
     	//特殊场景:1、中途需要显示释放  2、程序结束时,需要做一些特殊动作(如持久化)
     	static void DelInstance()
     	{
     		if (_ins)
     		{
     			delete _ins;//会调用析构函数
     		}
     	}
    
     	//5. 如何在程序结束后也调用析构函数?
     	//写一个类,将DelInstance交给GC管理,当程序结束,GC生命周期结束,编译器会调用其析构,
     	//此时就顺便将DelInstance执行
     	static class GC
     	{
     	public:
     		~GC()
     		{
     			DelInstance();
     		}
     	};
    
     private:
     	//1. 构造函数私有
     	OnlyOne()
     	{
     		//......
     	}
    
     	//delete会调用析构函数,由于是在类内部,所以能调用;程序结束不会调用析构函数,因为析构函数私有,
     	//所以在析构函数中所做的一些事情就不能实现,所以需要显示释放
     	~OnlyOne()
     	{
     		//......
     	}
    
     	//3. 防拷贝
     	OnlyOne(const OnlyOne& oo) = delete;
     	OnlyOne operator=(const OnlyOne& oo) = delete;
    
     	static OnlyOne* _ins;
     	static GC _gc;
     };
     OnlyOne* OnlyOne::_ins = nullptr;
     OnlyOne::GC OnlyOne::_gc;
     //优点:1.第一次调用GetInstance才创建对象,不会影响启动速度
     //2.不用担心启动顺序,想让谁创建单例子就让谁GetInstance。

    }

相关推荐
咸鱼2.05 分钟前
【java入门到放弃】跨域
java·开发语言
skiy1 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql
一念春风1 小时前
智能文字识别工具(AI)
开发语言·c#·wpf
桦01 小时前
【C++复习】:继承
开发语言·c++
何仙鸟2 小时前
GarmageSet下载和处理
java·开发语言
鱼难终2 小时前
类和对象(下)
c++
wefly20172 小时前
免安装!m3u8live.cn在线 M3U8 播放器,小白也能快速上手
java·开发语言·python·json·php·m3u8·m3u8在线转换
云泽8082 小时前
深入 AVL 树:原理剖析、旋转算法与性能评估
数据结构·c++·算法
薛先生_0992 小时前
js学习语法第一天
开发语言·javascript·学习
报错小能手3 小时前
深入理解 Linux 虚拟内存管理
开发语言·操作系统