如何有条件地实例化不同的父/子类
How to instantiate different parent/child classes conditionally?
类似的问题在这里和这里发布并回答,但建议的解决方案对我不起作用。
我有三个具有多级继承的类:
class Model
{
public:
Model();
template <typename InputModelType>
void importModel(const InputModelType &m);
virtual void process();
};
class SpecialModel : public Model
{
public:
SpecialModel();
template <typename InputModelType>
void importSpecialModel(const InputModelType &m);
virtual void process() override;
};
class SpecialSpecialModel : public SpecialModel
{
public:
SpecialModel();
template <typename InputModelType>
void importSpecialSpecialModel(const InputModelType &m);
virtual void process() override;
};
子模型是父模型的特例,可以存储在更简单的结构中,因此可以更快地处理。
我想做的是根据用户指定的输入参数model_type
实例化模型,如下所示:
Model* model;
switch(model_type){
case 1:
model = new SpecialModel;
model->importSpecialModel(gm);
break;
case 2:
model = new SpecialSpecialModel;
model->importSpecialSpecialModel(gm);
break;
default:
model = new Model;
model->importModel(gm);
break;
}
model->process();
使用上面的代码,我得到以下错误:
">类模型"没有名为"importSpecialModel"的成员
">类模型"没有名为"importSpecialSpecialModel"的成员
问题是,导入函数是模板化的,因此将它们定义为基类中的虚函数然后在子类中重写是无效的。
您只能使用对象的静态类型的函数。您可以执行以下操作,使用派生类型。
std::unique_ptr<Model> CreateModel(int model_type, const InputModelType &m)
{
switch(model_type)
{
case 1:
{
auto model = std::make_unique<PairwiseMRF>();
model->importSpecialModel(gm);
return model; // or std::move(model)
}
case 2:
{
auto model = std::make_unique<PairwiseMetricMRF>();
model->importSpecialSpecialModel(gm);
return model; // or std::move(model)
}
default:
{
auto model = std::make_unique<Model>();
model->importModel(gm);
return model;
}
}
}
然后
auto model = CreateModel(model_type, gm);
model->process();
这是
@Jarod42答案的变体。通过使用函数指针映射,可以避免使用 switch
语句。
// Independent functions to import the various model types
std::unique_ptr<Model> importPairwiseMRF(GmType gm)
{
auto model = std::make_unique<PairwiseMRF>();
model->importSpecialModel(gm);
return model;
}
std::unique_ptr<Model> importPairwiseMetricMRF(GmType gm)
{
auto model = std::make_unique<PairwiseMetricMRF>();
model->importSpecialSpecialModel(gm);
return model;
}
std::unique_ptr<Model> importModel(GmType gm)
{
auto model = std::make_unique<Model>();
model->importModel(gm);
return model;
}
// Function to import a model given a model_type and the import data.
std::unique_ptr<Model> importModel(int model_type, GmType gm)
{
// Define a function type that can take gm and return a Model*
typedef = std::unique_ptr<Model> (*Function)(GmType gm);
// Create a map of the functions known so far.
std::map<int, Function> theMap =
{
{1, importPairwiseMRF},
{2, importPairwiseMetricMRF},
{3, importModel}
};
// If there is a function for the given model_type, use it.
// Otherwise, return nullptr.
if ( theMap[model_type] != nullptr )
{
return theMap[model_type].second(gm);
}
else
{
return {};
}
}
并将其用作:
auto model = importModel(model_type, gm);
if ( model )
{
model->process();
}
相关文章:
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- C++有没有办法强制重写一组方法,如果其中一个方法在子类中具有重写?
- 当子类需要在 c++ 中相互包含时,继承有缺陷
- 有没有办法在C++中调用基类的所有子类函数?
- C++可以有条件地向下转换类指针吗
- 是否有 lint 工具可以检查子类虚拟函数是否与父类定义匹配?
- 有条件地启用类C++构造函数
- C ;使用lambdas在类中有条件地扩展功能(MWE的SEG故障)
- 如何有条件地实例化不同的父/子类
- 有条件地删除模板类中的方法
- 有没有办法在不重新实现的情况下从子类中标记父级的虚拟函数 final。
- 有没有更好的方法可以从子类访问父类的变量?
- 是否有必要调用父构造函数而不使用子类构造函数的参数?
- 我们如何有证据表明,声明虚拟函数的类是2个字节,其中一个不超过一个未声明,而在子类中
- 有条件地实例化具有删除默认构造函数的类
- 如果有许多具有相似名称的子类,如何进行优化
- 创建 QQuickItem 子类的实例是否有问题,我不打算渲染或添加到 QML 树中的实例?
- C++中包含父类对象的子类有什么问题(如果有的话)
- 如何有条件地实例化不同的子类