c++特殊类
创始人
2024-04-14 10:17:43
0

目录

1.实现一个只能在堆上创建对象的类(了解思想)

2.实现一个只能在栈上创建对象的类(同样思想最重要)

3.单例模式(有实际应用价值)


1.实现一个只能在堆上创建对象的类(了解思想)

实现原理:为了不开出静态变量和在栈上开变量有两种方式

方式一:将析构函数私有,然后手动实现一个有析构功能的成员函数,调用该函数即可。

方式二:将构造函数私有,然后手动实现一个返回new出来对象的成员函数。比较坑的是,要注意将拷贝构造和赋值都屏蔽掉。因为,在用拷贝构造和赋值时,还会使用构造函数。

方式一:

#includeusing namespace std;//方式1
class HeapOnly
{
public:void Delete() //手动实现释放{cout << "Delete by myself" << endl;delete this;}
private:~HeapOnly() //析构私有{}int _a;
};
int main()
{HeapOnly h1;static HeapOnly h2;HeapOnly* h3 = new HeapOnly;h3->Delete();return 0;
}

不屏蔽静态和栈上的会报错 。

 

 方式二:

//方式二
class HeapOnly
{
public:static HeapOnly* GetRet()  //手动new一个返回{cout << "new by myself" << endl;HeapOnly* ret=new HeapOnly;return ret;}HeapOnly(const HeapOnly& hp) = delete; //屏蔽拷贝构造和赋值HeapOnly operator=(const HeapOnly& hp) = delete;private:HeapOnly() //构造私有{}int _a;
};
int main()
{//HeapOnly h1;//static HeapOnly h2;HeapOnly* h = HeapOnly::GetRet();return 0;
}


2.实现一个只能在栈上创建对象的类(同样思想最重要)

由于,栈不能和堆一样手动写一个函数进行销毁。因此只能私有构造函数。

class StackOnly
{
private:int _a;StackOnly():_a(0){}
public:static StackOnly GetRet(){cout << "get by myself" << endl;StackOnly ret;return ret;}//上面涉及拷贝(传值返回),所以不能禁用拷贝,因此解决不了创建静态对象的问题。。/*StackOnly(const StackOnly& st) = delete;StackOnly operator=(const StackOnly& st) = delete;*/void* operator new(size_t n) = delete; //可以把new对象屏蔽。
};
int main()
{//HeapOnly h1;//static HeapOnly h2;/*HeapOnly* h = HeapOnly::GetRet();*/StackOnly st1 = StackOnly::GetRet();//StackOnly* st2 = new(StackOnly);return 0;
}


3.单例模式(有实际应用价值)

单例模式是指一个类只能创建一个对象。这个实例可以被全局访问,被所有模块共享。

实现方式1:饿汉模式

饿汉指的是,无论你是否使用该实例,程序启动就创建一个实例对象。

class singleton
{
public: singleton* GetInstance(){return &m_instance;  //方便拿出_instance}singleton(const singleton& sl) = delete; //屏蔽掉拷贝和赋值singleton operator=(const singleton& sl) = delete;private:singleton() //只能实例化一次,因此构造一定要私有。:_a(0){}static singleton m_instance; //静态初始化成员,方便马上直接拿出来。int _a;
};singleton singleton::m_instance; //在主程序开始前就实例化int main()

 优点:简单,不存在线程安全的问题。

缺点:拖延程序启动时间,如果有多个单例模式初始化的单例顺序不一定准。

实现方式2:懒汉模式

懒汉指的是,第一次使用对象时再实例化。

class MemoryPool
{
public:static	MemoryPool* GetInstance(){if (_pinst == nullptr){_pinst = new MemoryPool; //用时初始化一次}return _pinst;}class CGarbo { //内嵌垃圾回收类public:~CGarbo(){if (_pinst)delete _pinst;}};
private:MemoryPool() //只能实例化一次,因此构造一定要私有。{}char* _ptr=nullptr;static MemoryPool* _pinst;
};MemoryPool* MemoryPool::_pinst = nullptr; //创建单例对象
static MemoryPool::CGarbo gc; //通过调用内嵌类的析构实现资源释放。

优点:不会拖延程序启动时间,可以确定单例对象实例的循序。

缺点:复杂,存在线程安全的问题。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...