《Head First 设计模式》例子的C++实现(4 单件模式)

#《Head First 设计模式》例子的C++实现(4 单件模式)

单件模式使用场景比较多。基本的实现要点就是将构造函数设为私有的,这样就不能随便生成变量了。

下面是一个简单的代码示例,没有考虑多线程情况。
ChocolateBoiler 类也不希望别人拷贝,所以也把拷贝构造函数设为私有了。另外 C++与 java 最大的不同是 C++ 需要自己处理资源释放问题。所以还需要个 releaseInstance() 函数。


class ChocolateBoiler
{
public:
    void boil();
    bool isEmpty();
    bool isBoiled();
    void fill();
    void drain();
static ChocolateBoiler& getInstance();
static void releaseInstance() {delete m_uniqueInstance; m_uniqueInstance = nullptr;}
private:
    ChocolateBoiler();
    ChocolateBoiler(ChocolateBoiler &cb){}
    bool m_empty;
    bool m_boiled;
    static ChocolateBoiler * m_uniqueInstance;
};


ChocolateBoiler * ChocolateBoiler::m_uniqueInstance = nullptr;

ChocolateBoiler::ChocolateBoiler()
: m_empty(true), m_boiled(false)
{

}


ChocolateBoiler& ChocolateBoiler::getInstance()
{
    if (m_uniqueInstance == nullptr)
    {
        std::cout << "Creating unique instance of Chocolate Boiler" << std::endl;
        m_uniqueInstance = new ChocolateBoiler();
    }
    std::cout << "Returning instance of Chocolate Boiler" << std::endl;
    return *m_uniqueInstance;
}
void ChocolateBoiler::boil()
{
    std::cout << this << " : boil" << std::endl;
    if (!isEmpty() && !isBoiled())
    {
        // bring the contents to a boil
        m_boiled = true;
    }
}

bool ChocolateBoiler::isEmpty()
{
    return m_empty;
}

bool ChocolateBoiler::isBoiled()
{
    return m_boiled;
}

void ChocolateBoiler::fill()
{
    std::cout << this << " : fill" << std::endl;
    if (isEmpty())
    {
        m_empty = false;
        m_boiled = false;
        // fill the boiler with a milk/chocolate mixture
    }
}
void ChocolateBoiler::drain()
{
    std::cout << this << " : drain" << std::endl;
    if (!isEmpty() && isBoiled())
    {
        // drain the boiled milk and chocolate
        m_empty = true;
    }
}

测试代码如下:

    ChocolateBoiler& boiler = ChocolateBoiler::getInstance();
    boiler.fill();
    boiler.boil();
    boiler.drain();

    ChocolateBoiler& boiler2 = ChocolateBoiler::getInstance();
    boiler2.fill();
    boiler2.boil();
    boiler2.drain();
    
    ChocolateBoiler::releaseInstance();

    ChocolateBoiler& boiler3 = ChocolateBoiler::getInstance();
    boiler3.fill();
    boiler3.boil();
    boiler3.drain();

输出结果如下:

Creating unique instance of Chocolate Boiler
Returning instance of Chocolate Boiler
0000028A02ED4F40 : fill
0000028A02ED4F40 : boil
0000028A02ED4F40 : drain
Returning instance of Chocolate Boiler
0000028A02ED4F40 : fill
0000028A02ED4F40 : boil
0000028A02ED4F40 : drain
Creating unique instance of Chocolate Boiler
Returning instance of Chocolate Boiler
0000028A02ED4F80 : fill
0000028A02ED4F80 : boil
0000028A02ED4F80 : drain


如果利用局部静态变量的特性。上面的代码还可以精简:

ChocolateBoiler& ChocolateBoiler::getInstance()
{
    static ChocolateBoiler cb;
    return cb;
}

这样 releaseInstance() 也不需要了。而且也不用考虑多线程加锁问题了。

猜你喜欢

转载自blog.csdn.net/liyuanbhu/article/details/83478835