C++实现面试常见设计模式(未完待续)

单例模式

1.懒汉模式

GetInstance()使用懒惰初始化,也就是说它的返回值是当这个函数首次被访问时被创建的。这是一种防弹设计——所有GetInstance()之后的调用都返回相同实例的指针。

class CSingleton{
public:
    static CSingleton* GetInstance(){
        if (m_pInstance == nullptr)
            m_pInstance = new CSingleton();
        return m_pInstance;
    }
    ~CSingleton(){};
private:
    CSingleton(){};
    Singleton(Singleton)=delete;//?????
    Singleton operator=(const Singleton)=delete;//?????
    static CSingleton* m_pInstance;
}
Singleton* Singleton::m_instance_ptr = nullptr;

线程安全的懒汉模式:

class Singleton{
public:
    typedef std::shared_ptr Ptr;
    ~Singleton(){
        std::cout<<"destructor called!"<<std::endl;
    }
    Singleton(Singleton&)=delete;
    Singleton& operator=(const Singleton&)=delete;
    static Ptr get_instance(){

        // double checked lock
        if(m_instance_ptr==nullptr){
            std::lock_guard lk(m_mutex);
            if(m_instance_ptr == nullptr){
              m_instance_ptr = std::shared_ptr(new Singleton);
            }
        }
        return m_instance_ptr;
    }


private:
    Singleton(){
        std::cout<<"constructor called!"<<std::endl;
    }
    static Ptr m_instance_ptr;
    static std::mutex m_mutex;
};

2.饿汉模式

class CSingleton{
private:
    CSingleton(){}
pubic:
    static CSingleton* GetInstance(){
        static CSingleton* instance;
        return instance;
    }
}

多线程模式下会出问题的,线程安全的饿汉模式如下:

class CSingleton  
{  
private:  
    static CSingleton* m_instance;  
    CSingleton(){}  
public:  
    static CSingleton* getInstance();  
};  

CSingleton* CSingleton::getInstance()  
{  
    if(NULL == m_instance)  
    {  
        Lock();//借用其它类来实现,如boost  
        if(NULL == m_instance)  
        {  
            m_instance = new Singleton;  
        }  
        UnLock();  
    }  
    return m_instance;  
} 

3.Magic Static

#include 

class Singleton
{
public:
    ~Singleton(){
        std::cout<<"destructor called!"<

这种方法又叫做 Meyers' SingletonMeyer's的单例, 是著名的写出《Effective C++》系列书籍的作者 Meyers 提出的。所用到的特性是在C++11标准中的Magic Static特性:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
如果当变量在初始化的时候,并发同时进入声明语句,并发线程将会阻塞等待初始化结束。
请在这里输入引用内容
这样保证了并发线程在获取静态局部变量的时候一定是初始化过的,所以具有线程安全性。

C++静态变量的生存期 是从声明到程序结束,这也是一种懒汉式。

这是最推荐的一种单例实现方式:

通过局部静态变量的特性保证了线程安全 (C++11, GCC > 4.3, VS2015支持该特性);
不需要使用共享指针,代码简洁;
注意在使用的时候需要声明单例的引用 Single& 才能获取对象。

观察者模式

Subject(目标)

  • 目标知道它的观察者。可以有任意多个观察者观察同一个目标;
  • 提供注册和删除观察者对象的接口。

Observer(观察者)

  • 为那些在目标发生改变时需获得通知的对象定义一个更新接口。

ConcreteSubject(具体目标)

  • 将有关状态存入各ConcreteObserver对象;
  • 当它的状态发生改变时,向它的各个观察者发出通知。

ConcreteObserver(具体观察者)

  • 维护一个指向ConcreteSubject对象的引用;
  • 存储有关状态,这些状态应与目标的状态保持一致;
  • 实现Observer的更新接口以使自身状态与目标的状态保持一致。

https://www.cnblogs.com/carsonzhu/p/5770253.html

工厂模式

工厂模式包括三种:简单工厂模式、工厂方法模式、抽象工厂模式。

工厂模式的主要作用是封装对象的创建,分离对象的创建和操作过程,用于批量管理对象的创建过程,便于程序的维护和扩展。

1.简单工厂模式

简单工厂是工厂模式最简单的一种实现,对于不同产品的创建定义一个工厂类,将产品的类型作为参数传入到工厂的创建函数,根据类型分支选择不同的产品构造函数。

//简单工厂模式
typedef enum ProductTypeTag
{
    TypeA,
    TypeB,
    TypeC
}PRODUCTTYPE;

class Product//产品抽象基类
{
public:
    virtual void Show() = 0;
};

class ProductA : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductA"<Show();
    productB->Show();
    productC->Show();
    if(productA){
        delete productA;
        productA=NULL;
    }
    if(productB){
        delete productB;
        productB=NULL;
    }
    if(productC){
        delete productC;
        productC=NULL;
    }
    return 0;
}

2.工厂方法模式

其实这才是正宗的工厂模式,简单工厂模式只是一个简单的对创建过程封装。工厂方法模式在简单工厂模式的基础上增加对工厂的基类抽象,不同的产品创建采用不同的工厂创建(从工厂的抽象基类派生),这样创建不同的产品过程就由不同的工厂分工解决:FactoryA专心负责生产ProductA,FactoryB专心负责生产ProductB,FactoryA和FactoryB之间没有关系;如果到了后期,如果需要生产ProductC时,我们则可以创建一个FactoryC工厂类,该类专心负责生产ProductC类产品。

该模式相对于简单工厂模式的优势在于:便于后期产品种类的扩展。

//工厂方法模式
typedef enum ProductTypeTag
{
    TypeA,
    TypeB,
    TypeC
}PRODUCTTYPE;

class Product//产品抽象基类
{
public:
    virtual void Show() = 0;
};

class ProductA : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductA"<createProduct();
    productA->Show();
    Factory *factoryB=new FactoryB();
    Product *productB = factoryB->createProduct();
    productB->Show();
    if (factoryA)
    {
        delete factoryA;
        factoryA = NULL;
    }
    if (factoryB)
    {
        delete factoryB;
        factoryB = NULL;
    }
    if (productA)
    {
        delete productA;
        productA = NULL;
    }
    if (productB)
    {
        delete productB;
        productB = NULL;
    }
    return 0;
}

3.抽象工厂模式

抽象工厂模式对工厂方法模式进行了更加一般化的描述。工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,就是当具有多个抽象产品类型时,抽象工厂便可以派上用场。

抽象工厂模式更适合实际情况,受生产线所限,让低端工厂生产不同种类的低端产品,高端工厂生产不同种类的高端产品。

//抽象工厂模式
class ProductA
{
public:
    virtual void Show() = 0;
};

class ProductA1 : public ProductA//A类低端产品
{
public:
    void Show()
    {
        cout<<"I'm ProductA1"<CreateProductA();
    ProductB *productB1 = factory1->CreateProductB();
    productA1->Show();
    productB1->Show();
    Factory *factory2 = new Factory2();
    ProductA *productA2 = factory2->CreateProductA();
    ProductB *productB2 = factory2->CreateProductB();
    productA2->Show();
    productB2->Show();
    if (factory1)
    {
        delete factory1;
        factory1 = NULL;
    }
    if (productA1)
    {
        delete productA1;
        productA1= NULL;
    }
    if (productB1)
    {
        delete productB1;
        productB1 = NULL;
    }
    if (factory2)
    {
        delete factory2;
        factory2 = NULL;
    }
    if (productA2)
    {
        delete productA2;
        productA2 = NULL;
    }
    if (productB2)
    {
        delete productB2;
        productB2 = NULL;
    }
}

你可能感兴趣的:(基础知识整理,软件设计模式,c++,设计模式,java,spring,数据库)