C++ 这样做更好吗?

C++ 这样做更好吗?,c++,C++,我正在做一些似乎可以改进的事情,但我没有足够的技能来改进它。你能帮忙吗 鉴于: vector<Base*> stuff; const vector<MetaData>& metaDataContainer = Config.getMetaData(); for(vector<MetaData>::const_iterator i = metaDataContainer.begin(), end = metaDataContainer.end(); i

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

鉴于:

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语句很糟糕,因为在编译时,所有的枚举值都是已知的,所以理论上我们已经知道什么类型需要进入向量。但我们是在运行时这样做的


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

不太好。但是,您可以使用and或智能指针容器抽象出大部分样板文件,以智能方式管理资源。关于智能容器和智能指针的哑容器之间的选择。

不太可能。但是,您可以使用and或智能指针容器抽象出大部分样板文件,以智能方式管理资源。关于智能指针的智能容器和哑容器之间的选择。

好的,您可以预先分配一个映射元->函数来创建所需的派生类型

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]))());
}

-但这种方法可能太低级,而且容易出错。希望C++初始化允许这样的初始化。

,你可以预先分配一个映射元函数,它创建所需的派生类型。
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]))());
}
-但这种方法可能太低级,而且容易出错。希望这种初始化是C++语法允许的。

< p>你询问工厂模式。你可以用谷歌搜索。为了在编译时w.r.t.运行时尽可能多地使用搜索词,您可能需要使用模板添加搜索词

但是,由于元数据向量在运行时包含信息,因此需要一些动态的内容。枚举并不是一个坏主意-看看这里,例如:。 还要注意typedef instanceormap::value_type instanceormapentrytype末尾的位。使用工厂时枚举到成员函数指针的映射。

您询问的是工厂模式。你可以用谷歌搜索。为了在编译时w.r.t.运行时尽可能多地使用搜索词,您可能需要使用模板添加搜索词

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]();
}
但是,由于元数据向量在运行时包含信息,因此需要一些动态的内容。枚举并不是一个坏主意-看看这里,例如:。
还要注意typedef instanceormap::value_type instanceormapentrytype末尾的位。作为工厂使用枚举到成员函数指针的映射。

在编译时,所有枚举值都是已知的-您的意思是知道metaDataContainer的内容?看起来不是那样的。switch是实现工厂模式的一种好方法。你说得对,我不知道容器包含什么,但我知道它可能包含的所有可能值。因此,如果元数据是带有A、B、C的枚举。我知道这些是可能的,但是,我可能只得到A和C。在编译时,所有枚举值都是已知的-你是说你知道metaDataContainer的内容?看起来不是那样的。switch是实现工厂模式的一种好方法。你说得对,我不知道容器包含什么,但我知道它可能包含的所有可能值。所以如果元数据是带有A,B,C的enum。我知道这些是可能的,但是,我可能只得到A和C。啊,你可能想更新你的问题的标题。。。如果可能的话。啊,你可能想更新你的问题的标题。。。如果可能的话。地图构造器的好用法。地图构造器的好用法。
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]();
}