C高级编程工业模式下的单例
1、传统模式下的单例class Singleton { private: Singleton() { //std::cout << "单例构造函数" << std::endl; } // 禁用拷贝构造和赋值操作符 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; public: static Singleton* GetInstance() { return m_instance; } static void FreeInstance() { if (m_instance != nullptr) { delete m_instance; m_instance = nullptr; } } private: static Singleton* m_instance; }; Singleton* Singleton::m_instance = new Singleton;int main() { Singleton* pInstance = Singleton::GetInstance(); Singleton* pInstance2 = Singleton::GetInstance(); if (pInstance == pInstance2) { std::cout << "两个指针指向同一个对象" << std::endl; } else { std::cout << "两个指针指向未同一个对象" << std::endl; } }
测试输出:
单例构造函数
两个指针指向同一个对象 2、工业模式下的单例class MySingleClass { private: std::string name; public: MySingleClass(const std::string& n) :name(n) { std::cout << "左值构造函数" << std::endl; } MySingleClass(const std::string&& n) :name(n) { std::cout << "右值构造函数" << std::endl; } void PrintName() { std::cout << name << std::endl; } ~MySingleClass() { std::cout << "调用析构函数" << std::endl; } };template class Global final { public: static T* Get() { return *GetPPtr(); } template static void New(Args&&... args) { assert(Get() == nullptr); *GetPPtr() = new T(std::forward(args)...); } static void Delete() { if (Get() != nullptr) { delete Get(); *GetPPtr() = nullptr; std::cout << "删除对象" << std::endl; } } private: static T** GetPPtr() { static T* ptr = nullptr; return &ptr; } };int main() { // 创建一个单例,直接调用临时对象的构造函数, // 语句结束之后,调用 MySingleClass 的析构函数 // 将所有权转移给了Global Global::New(MySingleClass("123")); // 获取对象的指针,调用对象的成员方法 Global::Get()->PrintName(); // 删除获取到的单例 Global::Delete(); }
测试输出:
右值构造函数
调用析构函数
123
调用析构函数
删除对象 3、总结
工业模式下的单例的知识点用到了模板、可变参模板、二级指针、以及完美转发,此单例可以接受各种对象以及类的多种构造函数所成的对象,这种功能可变参模板起到了非常重要的作用,完美转发即参数是左值,完美转发之后也是左值,完美转发参数是右值,完美转发之后也是右值。