代码之家  ›  专栏  ›  技术社区  ›  anio

更好的方法?

c++
  •  1
  • anio  · 技术社区  · 14 年前

    我正在做一些看起来可以改进的事情,但我没有足够的技能来改进它。你能帮忙吗?

    鉴于:

    vector<Base*> stuff;
    const vector<MetaData>& metaDataContainer = Config.getMetaData();
    
    for(vector<MetaData>::const_iterator i = metaDataContainer.begin(), end = metaDataContainer.end(); i != end; ++i)
    {
      Base* pCurrent = buildDerivedType(*i);
      stuff.push_back(pCurrent);
    }
    
    Base* buildDerivedType(MetaData meta)
    {
      Base* pRetval = NULL;
    
      switch(meta)
      {
        case MetaData::A:
        pRetval = new Alpha();
        break;
    
        case MetaData::B:
        pRetval = new Beta();
        break;
    
        //so on so forth
      };
      return pRetval;
    }
    

    我觉得switch语句很糟糕,因为在编译时所有枚举值都是已知的,所以理论上我们已经知道了哪些类型需要进入向量类的东西中。但我们在运行时这样做。

    除了为此编写代码生成器之外,还有更好的方法吗?

    4 回复  |  直到 14 年前
        2
  •  3
  •   Vlad    14 年前

    typedef Base* ((*DerivedTypeCreator)());
    map <MetaData, DerivedTypeCreator> derivedTypeBuilders;
    
    // ...
    derivedTypeBuilders[MetaData::A] = &CreateAlpha;
    derivedTypeBuilders[MetaData::B] = &CreateBeta;
    
    Base* CreateAlpha()
    {
        return new Alpha();
    }
    
    Base* CreateBeta()
    {
        return new Beta();
    }
    
    // ...
    for(vector<MetaData>::const_iterator i = metaDataContainer.begin(),
            end = metaDataContainer.end();
        i != end; ++i)
    {
        stuff.push_back((*(derivedTypeBuilders[*i]))());
    }
    

    DerivedTypeCreator[] derivedTypeBuilders = {
        &CreateAlpha, // Metadata::A == 0
        &CreateBeta   // Metadata::B == 1
    };
    
    // ...
    stuff.push_back((*(derivedTypeBuilders[(int)*i]))());
    

        3
  •  2
  •   Gene Bushuyev    14 年前
    template<class T> Base* Creator() { return new T; }
    typedef Base* (*CreateType)();
    typedef std::pair<const MetaData, CreateType> cpair;
    
    cpair mapper [] =
    {
        cpair(MetaA, Creator<A>),
        cpair(MetaB, Creator<B>),
    };
    
    std::map<MetaData, CreateType> typemap(&mapper[0], &mapper[sizeof(mapper)]);
    
    void foo(MetaData m)
    {
        Base* a = typemap[m]();
    }
    
        4
  •  0
  •   towi    14 年前

    enum http://www.daniweb.com/forums/thread18399.html typedef InstantiatorMap::value_type InstantiatorMapEntryType