c++ - 具有派生类实例的工厂

标签 c++ c++11 inheritance design-patterns polymorphism

我遇到了一个奇怪的用例。这是它的一个非常简化的版本。

假设我有一个类 Base和类(class) DerivedOneDerivedTwo源自 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/

相关文章:

c++ - 如何使用美元/欧元符号登录代码来初始化变量?

c++ - 在 makefile 中添加 c++11 以消除错误 to_string is not declared in this scope

c++ - 在 C++11 中结合使用 std::function

c++ - 在C++中使用全局变量初始化

c++ - C++中的类继承

c++ - 从 vector 类的 vector 中读取数据 - C++

c++ - 将静态库与另一个静态库链接并在 exe 中使用主库

c++ - libtorrent-rasterbar7 : g++ linker unable to find libtorrent/session. hpp

c++ - 是否允许主线程在进入 main() 之前生成 POSIX 线程?

C++ 奇怪的重复模板模式,语法错误