【问题标题】:c++: Dynamically choose which subclass to createc++:动态选择要创建的子类
【发布时间】:2010-01-24 01:13:56
【问题描述】:

我是 C++ 新手,我有一个问题。

假设我们有一个基类 Base 和两个派生类 Derived1 和 Derived2。 f.e. Derived1 有一个采用整数的构造函数,而 Derived2 有一个采用布尔值的构造函数。

是否可以在运行时(或在编译时)确定创建这两个子类中的哪一个并将其分配给基类。

类似这样的: Base b = ???(value),其中 value 的类型为整数或布尔值。

提前致谢!

【问题讨论】:

  • 如果您习惯于 Java,请记住在 C++ 中,Base b 声明一个 object,而不是对对象的引用。如果您将派生对象分配给基础对象,那么它将被切片(假设它甚至可以编译)。对于 C++ 中的动态多态性,您需要使用 AraK 的答案中的指针。
  • 你的课是做什么的?使用模板派生可能更有意义,即类似Derived<int> d(someInt);

标签: c++ class dynamic derived


【解决方案1】:

编写一个名为createMyBlaBla 的函数的两个重载。一个接受int,另一个接受bool。每个人都返回所需的派生类类型。例如:

Base* create(int n)
{
    return new Derived1(n);
}
Base* create(bool b)
{
    return new Derived2(b);
}
....
Base* b1 = create(10);    // Derived1
Base* b2 = create(false); // Derived2

人们称之为工厂模式。

【讨论】:

    【解决方案2】:

    你可能想要Factory Design Pattern

    【讨论】:

      【解决方案3】:

      我真的不认为这是你想要的方式, C++ 中的多态性就是不能这样工作。

      如果我理解得很好,你想要一个声明为 Base 决定的变量, 根据参数类型,它是 Derived1 还是 Derived2,完全没有使用工厂模式。

      这不可能的原因是,Base 类并没有真正意识到其Derived 的存在 类,您也不能声明堆栈变量并使其“表现”为派生类。但是,我可以建议一种解决方法,但话又说回来,这 不能满足你对真实类层次结构的所有期望 想要(如果你真的想要那样的话_:

      class Facade{
      
      public:
          Facade(int foo) : b(new Derived1(foo)){}
      
          Facade(bool foo) : b(new Derived2(foo)){}
      
          Base Value()
          {
              return *b;
          }
      
      private:
          Base* b;
      
      };
      

      然后您可以执行以下操作:

      Facade foo(10);
      Facade bar(true);
      
      int x = (reinterpret_cast<Derived1*>(foo.Value())) -> val;
      bool y = (reinterpret_cast<Derived2*>(bar.Value())) -> val;
      

      【讨论】:

      • 顺便说一下,reinterpret_cast 是不安全的……你最好改用 dynamic_cast。
      • 如果调用者确定运行时类型实际上是指定的派生类型,则向下转换应该使用 static_cast,否则应该使用 dynamic_cast(并检查 null)。您只能使用具有虚函数的 dynamic_cast 类,因此请确保有一个(如果您弄乱了指针和多态性,则析构函数可能是虚拟的)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2018-04-16
      • 2013-07-10
      • 1970-01-01
      • 2018-09-25
      • 2016-10-11
      • 2014-06-09
      相关资源
      最近更新 更多