c++ - 具有派生类实例的工厂
问题描述
我有一种奇怪的用例。这是它的一个非常简化的版本。
假设我有一个类Base
和类DerivedOne
,DerivedTwo
它们是从Base
该类派生的。
然后,有一个枚举:
enum DerClasses {Derived1, Derived2};
和一个函数,它将接受一个枚举并返回派生类的实例,具体取决于值。
就像是:
inline Base* create_instance(DerClasses enum_class){
switch(enum_class) {
case Derived1:
return new Derived1();
case Derived2:
return new Derived2();
}
}
显然这是可行的,但只能在之后强制转换为派生类。
Derived1 *derived_pointer = dynamic_cast<Derived1*>(pointer);
而且我不希望用户自己制作这些动态演员表,甚至对这些类一无所知。
是否有可能以某种方式隐藏这些演员表并制作一个具有自动类型推断的 API,例如
auto ptr = create_instance(DerClasses::Derived1);
ptr->derived1_class_only_variable = 123;
解决方案
template<DerClasses enum_class>
auto create_instance(){
if constexpr (enum_class == DerClasses::Derived1) {
return std::make_unique<Derived1>();
else if constexpr (enum_class == DerClasses::Derived2) {
return std::make_unique<Derived2>();
}
如果您在编译时不知道该DerClasses
值,则这不起作用,并且无法正常工作。您可以获得的最接近的是延续传递风格:
template<class F>
decltype(auto) create_instance(DerClasses enum_class, F&& f){
switch(enum_class) {
case DerClasses::Derived1:
return f(std::make_unique<Derived1>());
case DerClasses::Derived2:
return f(std::make_unique<Derived2>());
}
}
使用如下:
create_instance(DerClasses::Derived1, [&](auto&& ptr) {
if constexpr( std::is_same< std::decay_t<decltype(*ptr)>, Derived1 >{} )
ptr->derived1_class_only_variable = 123;
});
但这也很糟糕,因为 lambda 是用两种派生类型调用的;只有一个在运行。
使用覆盖可能会起作用,但你又要疯了。
推荐阅读
- javascript - JavaScript:如何动态定义方法?
- r - 数据问题:addAwesomeMarkers 需要 lng、lat,但我的数据存储在向量中。解决问题?
- python - 如何在 python 的 sklearn 中使用交叉验证执行 SMOTE
- javascript - Vue Apollo - 无法使用变量“无法分配给对象的只读属性'名称'”进行查询
- c# - 文本框下划线
- android - Volley JSONObject 请求解析响应返回无值
- php - CodeIgniter 数据库错误,但只有一部分应用程序
- python - 如何按照我需要的方式重塑这个数组?
- django - 如何在表单中使用 django_select2
- amazon-web-services - 失败:WebSocket 打开握手超时(亚马逊 AWS)