C++基础之设计模式-单例模式

参考文献:

(1) WiKi:https://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F

(2) 简单单例模式理解:https://blog.csdn.net/liang19890820/article/details/61615495

(3) 几种单例模式设计的优缺点:https://blog.csdn.net/Jack__Frost/article/details/66475741

(4) 优缺点详情:https://blog.csdn.net/cselmu9/article/details/51366946


//设计模式之单例模式:目的是使得类的一个对象在系统中只有唯一实例

#include <iostream>

template<typename _TYPE_>
class Singleton
{
public:
    static _TYPE_* instance() {
        static _TYPE_ obj;
        return &obj;  //避免默认的拷贝构造
    }
  
protected:  //CFile 可以构造和析构
    Singleton() {}
    ~Singleton() {}

private:
    Singleton(const Singleton &) {}  //避免默认的拷贝构造
    Singleton& operator = (const Singleton &) {}
};

class CFile : public Singleton<CFile>
{
public:
    void Init() { std::cout << "init " << ++m_num << std::endl; }
    
protected:
    CFile() { m_num = 0; std::cout << m_num << std::endl; }
    ~CFile() { m_num = 0; }
    friend Singleton<CFile>;  //如果构造为protected时,Singleton类中的instance函数要范围构造,则需为友元

private:
    int m_num;
};

int main()
{
    Singleton<CFile>::instance()->Init();
    Singleton<CFile>::instance()->Init();

    CFile *cfile_1 = Singleton<CFile>::instance();
    cfile_1->Init();

    //CFile *cfile_2 = new CFile();
    //cfile_2->Init();
    //cfile_2->instance()->Init();
    //delete cfile_2;

    CFile::instance()->Init();  //推荐用法

    CFile *cfile_3 = CFile::instance();
    cfile_3->Init();

    getchar();
    return 0;
}


Boost中也有单例模式的可继承实现,以下是类似例子,非单纯的单例模式:

#include <boost/noncopyable.hpp>  
#include <boost/serialization/singleton.hpp>  
#include <iostream>  

// 使用方式1:模板参数方式  
class CTest :public boost::noncopyable // 不能复制、赋值  
{
public:
    void Set(int i) { m_val = i; }
    void Print() const { std::cout << m_val << std::endl; }
private:
    int m_val;
};

// 使用typedef以及宏来简化使用  
typedef boost::serialization::singleton<CTest> singleton_ctest; // 使用模板的方式只允许单个实例  
#define sCTest singleton_ctest::get_mutable_instance() // 非const实例  
#define sCTest_const singleton_ctest::get_const_instance() // const实例  


// 使用方式2:继承方式  
class CDerived :public boost::serialization::singleton<CDerived> // 只允许单个实例,不能复制、赋值(基类派生自boost::noncopyable)  
{
public:
    void Set(int i) { m_val = i; }
    void Print() const { std::cout << m_val << std::endl; }

private:
    int m_val;
};

#define sCDerived CDerived::get_mutable_instance() // 非const实例  
#define sCDerived_const CDerived::get_const_instance() // const实例  

int main(void)
{
    //  singleton_ctest obj1;  
    //  singleton_ctest obj2;  
    sCTest.Set(10);
    sCTest_const.Print(); // 10  

    // 操作类的非static成员  
    CDerived cobj;
    CDerived cobj2;
    cobj2.Set(89);
    cobj.Set(10);

    // 单例的概念:并非是不能定义两个类对象本身  
    // 而是当有多个对象时,通过boost提供的静态成员函数get_mutable_instance()返回实例再调用普通成员函数之后,  
    // 类对象的结果保持一致,就好像类中的所有数据成员都是static一样  

    // 这时的类好像定义了两种同名的数据成员以及成员函数:static与非static  
    // 非static由普通方式调用:即先定义类对象,再调用成员函数  
    // static先调用由boost提供的get_mutable_instance()(或get_const_instance())再调用成员函数的方式  
    // 从而保证单例(因为类的所有成员共享static)  
    // 两种调用互不影响(各自数据成员是分离的),唯一的影响是类现在派生自boost::noncopyable  

    //操作类的“static成员”  
    CDerived::get_mutable_instance().Set(20);
    CDerived::get_mutable_instance().Print(); // 20  
    
    // same way:  
    sCDerived.Set(20);
    sCDerived.Print();  // 20  
    //sCDerived_const.Set(89); // error
    sCDerived_const.Print(); // 20  
    cobj2.get_mutable_instance().Print(); // 20  
    cobj.get_mutable_instance().Print(); // 20  

    // 操作类的非static成员  
    cobj2.Print(); // 89  
    cobj.Print(); // 10  

    // 实际使用中,我们没有必要也不应该直接定义类对象,而是应该总是通过使用类的static成员函数:  
    // classname::get_mutable_instance().memberFunction(para);(或get_const_instance())来确保“单个实例”  
    // 本例中定义的宏的使用方式与类对象的使用方式相同:name.member_function(para);  
    // 可以将宏当做“对象”  

    getchar();
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qccz123456/article/details/80254654
今日推荐