单例模式模板

//单例模板
template <typename T>
class Singleton 
{
    //使用默认构造和析构函数
    Singleton() = default;
    ~Singleton() = default;
public:
	//删除默认的移动、拷贝、赋值、取址
    Singleton(Singleton  &&) = delete;
    Singleton(const Singleton  &) = delete;
    void operator = (const Singleton  &) = delete;
    T *operator &() = delete;
    
    static T* instance()
    {
        static T object;
        return &object;
    }
};

使用示例:

//测试类
class Test
{
    int id;
public:
    void setId(int id)
    {
        this->id = id;
    }
    int getId() const
    {
        return this->id;
    }
};

int main()
{
    Singleton<Test>::instance()->setId(5);
    std::cout << Singleton<Test>::instance()->getId() << std::endl;
}

如果使用的时候觉得调用太长,可以将其 #define 一下,如:

#define SingletonTest Singleton<Test>::instance()

int main()
{
    SingletonTest->setId(5);
    std::cout << SingletonTest->getId() << std::endl;
}

到这里你可能会提出质疑,我们在此处并没有做到禁止创建 Test 用户类的对象,如果你有这样的需求,那请往下看
为了禁止擅自创建 Test(用户类对象),我们改变下策略:
放开模板限制,在此不再删除取址操作(会影响返回对象的引用),取消模板类构造函数的私有化,作为基类,析构函数标记为virtual;

//单例模式基类,CRTP模板
template <typename T>
class Singleton {
public:
    Singleton() = default;
    virtual ~Singleton() = default;
    Singleton(Singleton &&) = delete;
    Singleton(const Singleton &) = delete;
    void operator = (const Singleton &) = delete;

    static T* instance()
    {
        static T object;
        return &object;
    }
};

用户类继承单例模板
与之前不同的是,将创建对象的限制放在了用户类(即将构造函数设置为私有),构造函数私有化后,单例模板也无法创建对象,于是,将单例模板作为友元类, 模板类才能访问到用户类的构造函数

class Test : public Singleton<Test>
{
public:
    void setId(int id)
    {
        this->id = id;
    }
    int getId() const
    {
        return this->id;
    }
private:
    int id;
    Test() = default;
    
    //单例模板作为友元类
    friend class Singleton<Test>;
};

使用示例:

int main()
{
    //Test t;  //错误,禁止创建对象
    Test::instance()->setId(5);
    std::cout << Test::instance()->getId();
}

相关推荐

  1. 模式模板

    2024-03-14 17:32:01       43 阅读
  2. 模式模板

    2024-03-14 17:32:01       66 阅读
  3. 模式【C#】

    2024-03-14 17:32:01       54 阅读
  4. python模式

    2024-03-14 17:32:01       62 阅读
  5. 模式详解

    2024-03-14 17:32:01       61 阅读
  6. 模式学习

    2024-03-14 17:32:01       48 阅读
  7. 模式(C++)

    2024-03-14 17:32:01       49 阅读
  8. 设计模式

    2024-03-14 17:32:01       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 17:32:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 17:32:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 17:32:01       82 阅读
  4. Python语言-面向对象

    2024-03-14 17:32:01       91 阅读

热门阅读

  1. spring boot 获取服务器域名

    2024-03-14 17:32:01       35 阅读
  2. 功能测试--APP专项测试

    2024-03-14 17:32:01       43 阅读
  3. 第十三届蓝桥杯省赛C++ C组《全题目+题解》

    2024-03-14 17:32:01       34 阅读
  4. Python 实现一个简单的中文分词处理?

    2024-03-14 17:32:01       39 阅读
  5. [ffmpeg] 获取编译配置信息

    2024-03-14 17:32:01       35 阅读
  6. ffmpeg 通过遍历视频流,对视频帧进行打标

    2024-03-14 17:32:01       29 阅读
  7. Lua速成(1)

    2024-03-14 17:32:01       41 阅读
  8. Spring 整合 MyBatis、Junit

    2024-03-14 17:32:01       44 阅读