目录
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; //通过调用内嵌类的析构实现资源释放。
优点:不会拖延程序启动时间,可以确定单例对象实例的循序。
缺点:复杂,存在线程安全的问题。