可继承扩展的单例实现

最近在代码阅读中看到了一种可继承的单例实现,对使用者而言通过单例基类到定义的静态接口获取实例,而不必关心实际的单例实现。灵活性上,可通过继承的重写虚接口的方式实现单例功能的扩展。基础代码如下:

/* TestSingleton.h */

#include <iostream>
using namespace std;

#define ClassName(klass) (#klass)

class SingletonBase;
namespace
{
    SingletonBase* ptr_single_instance = nullptr;
}

class SingletonBase
{
public:
    SingletonBase();
    ~SingletonBase();

    // 虚接口
    virtual void TestSingleton();

    static SingletonBase* Get();
};

SingletonBase::SingletonBase()
{
    ptr_single_instance = this;
}

SingletonBase::~SingletonBase()
{

}

SingletonBase* SingletonBase::Get()
{
    return ptr_single_instance;
}

void SingletonBase::TestSingleton()
{
    cout << ClassName(SingletonBase) << std::endl;
}

class SingletonImp1 : public SingletonBase
{
public:
    SingletonImp1();
    ~SingletonImp1();

    virtual void TestSingleton() override;
};

SingletonImp1::SingletonImp1()
    : SingletonBase()
{

}

SingletonImp1::~SingletonImp1()
{
}

void SingletonImp1::TestSingleton()
{
    cout << ClassName(SingletonImp1) << std::endl;
}

void GoTest()
{
    //使用者实际选择创建何种单例,而不是在Get接口中new
    SingletonImp1* ptr_single_imp = new SingletonImp1();
    SingletonBase::Get()->TestSingleton();
}

当然在扩展性增强的同时也带来问题:相对于传统单例实现方式–在Get接口中new一个当前类型的实例,此种单例实例的创建暴露给了使用者,需要由使用者事先选择并创建指定子类型的实例,然后其他地方获取单例对象使用。

单例使用心得

单例便于单例类型中的接口调用,避免了类型上功能相互调用时参数传递的麻烦。但单例使用也存在一定的问题:
1. 单例的生命周期不易控制;
2. 单例使得类型间的依赖更加隐蔽且难以管理;
3. 单例中的定义的功能接口不易继承扩展:例如在项目开发中错误信息提示窗口统一在窗口右上角提示。实现上可通过定义消息提示的单例对象,在程序出错处调用单例对象的接口完成消息提示。随着功能的演进,又有了新的需求:消息不仅要在窗口右上提示,部分错误要以弹模态框的方式提示。因实例唯一,在接口不动的情况下通过继承的方式进行扩展显然是做不到的,而且单例接口变动带来的改动量也相当可观。所以功能接口功能比较稳定可封装为单例,如若不然就要为以后的功能变动买单。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值