【问题标题】:C++ Service ProvidersC++ 服务提供者
【发布时间】:2009-01-05 02:48:25
【问题描述】:

我一直在学习 C++,来自 C#,在那里我习惯了使用服务提供者:基本上是一个 Dictionary。不幸的是,我不知道如何在 C++ 中做到这一点。所以问题基本上是:

  1. 如何用 C++ 制作字典。

  2. 据我所知,C++ 中没有“Type”,我将如何使用“Type”。

  3. 与上述相同,但使用“对象”。

谢谢!

【问题讨论】:

    标签: c++ dictionary service


    【解决方案1】:

    我假设您正在尝试将类型映射到单个对象实例。您可以尝试以下方式:

    #include <typeinfo>
    #include <map>
    #include <string>
    using namespace std;
    
    class SomeClass
    {
    public:
        virtual ~SomeClass() {} // virtual function to get a v-table
    };
    
    struct type_info_less
    {
        bool operator() (const std::type_info* lhs, const std::type_info* rhs) const
        {
            return lhs->before(*rhs) != 0;
        }
    };
    
    class TypeMap
    {
        typedef map <type_info *, void *, type_info_less> TypenameToObject;
        TypenameToObject ObjectMap;
    
    public:
        template <typename T> 
        T *Get () const
        {
            TypenameToObject::const_iterator iType = ObjectMap.find(&typeid(T));
            if (iType == ObjectMap.end())
                return NULL;
            return reinterpret_cast<T *>(iType->second);
        }
        template <typename T> 
        void Set(T *value) 
        {
            ObjectMap[&typeid(T)] = reinterpret_cast<void *>(value);
        }
    };
    
    int main()
    {
        TypeMap Services;
        Services.Set<SomeClass>(new SomeClass());
        SomeClass *x = Services.Get<SomeClass>();
    }
    

    在 C++ 中,类型本身并不是一等对象,但至少类型名称是唯一的,因此您可以以此作为关键字。

    编辑:名称实际上并不能保证是唯一的,因此请保留 type_info 指针并使用 before 方法来比较它们。

    【讨论】:

    • 可以使用每个ServiceProvider类的静态属性的地址,而不是使用字符串
    • 错误:typeid(T).name 不是唯一的。 typeid(T) 确实有一个 operator== 来比较 typeinfo 对象。参见例如type_info_cmp on tangentsoft.net/mysql++/doc/html/refman/…
    【解决方案2】:

    您可能想查看STL map template。 C++ 确实有类型(没有它就很难继承),只是没有具体定义的“类型”类。

    【讨论】:

      【解决方案3】:

      STL 有两个关联容器:std::map&lt;K,V&gt; andstd::multimap。还有std::set&lt;V&gt; 应该是std::map&lt;V,void&gt; 的适配器,但它不是关联容器。 multimap 类似于 map,只是它允许在同一个容器内有多个相同的键。 map 和 multimap 都包含std::pair&lt;K,V&gt; 类型的元素。换句话说,std::map&lt;K,V&gt;::value_type == std::pair&lt;K,V&gt;,但是std::map&lt;K,V&gt;::key_type == Kstd::map&lt;K,V&gt;::mapped_type == V

      至于“类型”,我不完全确定您的意思。如果您指的是参数化类,那么 C++ 将其称为“模板编程”或“通用编程”。在上面,std::map&lt;K,V&gt; 在 K 和 V 上被参数化为键的类型和值的类型。 C++ 也支持模板函数:

      template<typename T>
      void f(T o);
      

      将声明一个函数,该函数接受任何类型作为参数,包括原始类型。 C++ 不支持泛型类型解析,因此类型 T 必须具有一定的层次结构。目前,您所能做的只是假设传递的类型确实具有正确的层次结构,如果您尝试对该类型的对象调用未声明的函数,编译器会报错。

      template<typename T>
      void f(T o) {
          o.do_it();
      }
      

      只要 T 定义了方法 do_it(),上述方法就可以工作。

      【讨论】:

        【解决方案4】:

        对我来说,字典听起来像是 STL 映射:std::map&lt;K, T&gt;。看看标准模板库——它很棒。一段时间以来,它一直是 ANSI C++ 的一部分。如果我没记错的话,微软有一个来自 PJ Plauger 的不错的实现。

        【讨论】:

        • 模板注释没有通过;应该读 std:map
        猜你喜欢
        • 2023-03-28
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 2020-12-21
        • 2017-01-11
        相关资源
        最近更新 更多