• [总结]C++实现一个限制对象实例个数的类


    C++实现一个限制对象实例个数的类

    absolute8511 总结于 09-3-2

    这个问题有两方面的需求,一个是单例模式,只能创建一个对象,另一种是限制创建的对象个数。这两种情况类似,实现原理也是类似的。

    它们的基本原理:1.构造函数私有化;2. 提供自己的静态构造函数

    对于单例模式,构造一个static对象,以后返回该对象即可。对于限制对象个数的多例模式,需添加一个静态字段记录创建的对象个数,在私有构造函数中对该字段进行检查,在析构函数递减该字段即可。

    实现如下:

    1. Counted类是所有需要应用该模式的基类。

    template<class BeingCounted> class Counted
    {
    public:
    class TooMany{};            //用于抛出异常的类,也可以在对象过多时返回NULL

    //用于客户端获取目前已有的对象个数
    static size_t objectCount()
    {
         return numObjects;
    }
    protected:
       Counted();
       Counted(const Counted& rhs);

    //析构函数使对象计数减1
       ~Counted()
       {
       --numObjects;
       }
    private:

    //记录对象个数
      static size_t numObjects;

    //允许的最多的对象个数,由派生类自己设定限制个数
      static const size_t maxObjects;
       void init();
    };
    template<class BeingCounted> size_t Counted<BeingCounted>::numObjects = 0;


    template<class BeingCounted> Counted<BeingCounted>::Counted()
    {
    init();
    }
    template<class BeingCounted> Counted<BeingCounted>::Counted(const Counted<BeingCounted>& rhs)
    {
    init();
    }
    template<class BeingCounted> void Counted<BeingCounted>::init()
    {
    if(numObjects>=maxObjects)
       throw TooMany();
    ++numObjects;
    }

    2. 对于需要单例模式的类可以实现如下,从Counted私有派生:

    class Limiter1:private Counted<Limiter1>
    {
    public:
    ~Limiter1();

    //由于私有继承,隐藏了以下两个东西,为了使客户端可见,使用using将它们加入到公有接口中
    using Counted<Limiter1>::objectCount;
    using Counted<Limiter1>::TooMany;
    static Limiter1& GetLimiter1Inst();
    private:
    Limiter1();
    Limiter1(const Limiter1& rhs);

    };

    //设定限制个数为1,即单例模式
    const size_t Counted<Limiter1>::maxObjects = 1;

    //客户端将调用该函数获取对象实例
    Limiter1& Limiter1::GetLimiter1Inst()
    {
    static Limiter1 Inst;
    return Inst;
    }
    Limiter1::Limiter1()
    {
    printf("Limiter1 created!\n");
    }
    Limiter1::~Limiter1()
    {
    printf("Limiter1 destroy!\n");
    }

    3. 限制一定个数的对象的实现方法:

    class Limiter2:private Counted<Limiter2>
    {
    public:
    static Limiter2* makeLimiter2();
    ~Limiter2();
    using Counted<Limiter2>::objectCount;
    using Counted<Limiter2>::TooMany;
    private:
    Limiter2();
    Limiter2(const Limiter2& rhs);

    };

    //限制对象个数为4
    const size_t Counted<Limiter2>::maxObjects = 4;

    //客户端调用该函数获取对象,由于new会调用基类的构造函数,而基类的构造函数会判断实例个数,因此实现了限制个数的目的
    Limiter2* Limiter2::makeLimiter2()
    {
    return new Limiter2();
    }
    Limiter2::Limiter2()
    {
    printf("Limiter2 created!");
    }
    Limiter2::~Limiter2()
    {
    printf("Limiter2 destroy!");
    }

  • 相关阅读:
    dotnet core 获取 MacAddress 地址方法
    dotnet core 获取 MacAddress 地址方法
    dotnet core 发布只带必要的依赖文件
    dotnet core 发布只带必要的依赖文件
    Developing Universal Windows Apps 开发UWA应用 问答
    Developing Universal Windows Apps 开发UWA应用 问答
    cmd 如何跨驱动器移动文件夹
    cmd 如何跨驱动器移动文件夹
    C++ 驱动开发 error LNK2019
    C++ 驱动开发 error LNK2019
  • 原文地址:https://www.cnblogs.com/absolute8511/p/1649603.html
Copyright © 2020-2023  润新知