我遇到了一个奇怪的用例。这是它的一个非常简化的版本。
假设我有一个类 Base
和类(class) 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 是用两种派生类型调用的;只有一个运行。
使用 override 可能会起作用,但你又一次变得疯狂。
关于c++ - 具有派生类实例的工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55498000/