c++特殊类

目录

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

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

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


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

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

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

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

方式一:

#include<iostream>

using 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; //通过调用内嵌类的析构实现资源释放。

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

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的运气选手^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值