目录
实现原理:为了不开出静态变量和在栈上开变量有两种方式
方式一:将析构函数私有,然后手动实现一个有析构功能的成员函数,调用该函数即可。
方式二:将构造函数私有,然后手动实现一个返回new出来对象的成员函数。比较坑的是,要注意将拷贝构造和赋值都屏蔽掉。因为,在用拷贝构造和赋值时,还会使用构造函数。
方式一:
- #include
-
- 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;
- }

由于,栈不能和堆一样手动写一个函数进行销毁。因此只能私有构造函数。
- 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;
- }

单例模式是指一个类只能创建一个对象。这个实例可以被全局访问,被所有模块共享。
实现方式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; //通过调用内嵌类的析构实现资源释放。
优点:不会拖延程序启动时间,可以确定单例对象实例的循序。
缺点:复杂,存在线程安全的问题。