加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Singleton mixin C.

发布时间:2020-12-16 10:31:18 所属栏目:百科 来源:网络整理
导读:简介:如何在C中创建单例mixin?我试图避免复制相同的get_instance()函数,私有构造函数等.但我无法找到一种方法使它成为mixin,因为静态实例将由从mixin继承的所有内容共享. 很容易使每个派生类成为单例,但有没有办法在不重复代码的情况下完成它?非常感谢你
简介:如何在C中创建单例mixin?我试图避免复制相同的get_instance()函数,私有构造函数等.但我无法找到一种方法使它成为mixin,因为静态实例将由从mixin继承的所有内容共享.

很容易使每个派生类成为单例,但有没有办法在不重复代码的情况下完成它?非常感谢你的帮助,我很难过.

码:
我正在编写一个带有Registry类的程序,用于按名称查找对象.

#include <string>
#include <memory>
#include <map>
#include <string>
#include <assert.h>

template <typename T>
class Registry
{
private:
  // make private so that the class can't be instantiated and must be used via get_instance
  Registry() {}
protected:
  std::map<std::string,std::shared_ptr<T> > name_to_object_ptr;
public:
  static Registry<T> & get_instance()
  {
    static Registry<T> instance;
    return instance;
  }
  void register_name(const std::string & name,T*obj_ptr)
  {
    assert( name_to_object_ptr.count(name) == 0 );
    name_to_object_ptr[name] = std::shared_ptr<T>(obj_ptr);
  }
  const std::shared_ptr<T> & lookup_name(const std::string & name)
  {
    assert( name_to_object_ptr.count(name) > 0 );
    return name_to_object_ptr[name];
  }
  int size() const
  {
    return name_to_object_ptr.size();
  }
};

我的注册表类是一个单例;它必须是一个单例(这样注册的对象不会消失).

class DerivedRegistryA : public Registry<int>
{
};

class DerivedRegistryB : public Registry<int>
{
};

int main()
{
  DerivedRegistryA::get_instance().register_name(std::string("one"),new int(1));
  std::cout << DerivedRegistryA::get_instance().size() << std::endl;
  DerivedRegistryA::get_instance().register_name(std::string("two"),new int(2));
  std::cout << DerivedRegistryA::get_instance().size() << std::endl;
  DerivedRegistryA::get_instance().register_name(std::string("three"),new int(3));
  std::cout << DerivedRegistryA::get_instance().size() << std::endl;

  DerivedRegistryB::get_instance().register_name(std::string("four"),new int(4));
  std::cout << DerivedRegistryB::get_instance().size() << std::endl;

  return 0;
}

输出:

1
2
3
4

期望的输出:

1
2
3
1

解决方法

什么狮子说听起来是正确的.这是一个与您的原始设计更相似的相关概念.

您声明一个模板类,其工作方式类似于Registry对象的工厂.我叫它RegAccess:

template <typename RegType>
class RegAccess
{
public:
  static RegType & get_instance()
  {
    static RegType instance;
    return instance;
  }
};

为了使它工作,你:

>声明RegAccess< Registry< T> > Registry的朋友< T> (为了能够做到这一点,你需要确保它在Registry< T>之前的某个地方定义)
>使Registry的构造函数受到保护,而不是私有(因此派生类的构造函数可以隐式使用它)
>从Registry< T>中删除get_instance方法.类定义

然后你的主程序变成:

int main()
{
  RegAccess<DerivedRegistryA>::get_instance().register_name(std::string("one"),new int(1));
  std::cout << RegAccess<DerivedRegistryA>::get_instance().size() << std::endl;
  RegAccess<DerivedRegistryA>::get_instance().register_name(std::string("two"),new int(2));
  std::cout << RegAccess<DerivedRegistryA>::get_instance().size() << std::endl;
  RegAccess<DerivedRegistryA>::get_instance().register_name(std::string("three"),new int(3));
  std::cout << RegAccess<DerivedRegistryA>::get_instance().size() << std::endl;

  RegAccess<DerivedRegistryB>::get_instance().register_name(std::string("four"),new int(4));
  std::cout << RegAccess<DerivedRegistryB>::get_instance().size() << std::endl;

  return 0;
}

当我测试它时,它产生了所需的输出.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读