代码之家  ›  专栏  ›  技术社区  ›  Moberg

在基类中使用“new this.getType()”实例化派生类

  •  0
  • Moberg  · 技术社区  · 15 年前

    我有一个基类A,类B和C是从它派生出来的。A是一个抽象类,三个类都有一个接受2个参数的构造函数。是否可以在基类A中生成这样的方法:

    A* clone() const
    {
        return new this.GetType(value1, value2);
    }
    

    如果当前调用clone()-函数的对象是C,那么函数将返回指向C类新对象的指针?

    4 回复  |  直到 15 年前
        1
  •  2
  •   tdammers    15 年前

    这看起来像C++.NET(又名“托管C++”),而不是纯的(标准)C++。我不是这方面的专家,但我的猜测(假设.NET)是您必须使用反射来实例化 System.Type . 通常的步骤是:

    1. 创建或获取合适的 Type 对象,例如通过调用 GetType .
    2. 找到合适的 ConstructorInfo ( Type.GetConstructors() IIRC)
    3. 呼叫 ConstructorInfo.Invoke() 创建实例
    4. 投射结果 System.Object 到所需类型。

    在常规C++中,根本不可能做到这一点,因为语言根本没有反射,类型信息在运行时大部分丢失(RTTI可以比较和测试对象的运行时类型,但这就是它)。您必须为每个派生类实现一个新的克隆方法;我通常使用的模式如下所示:

    class Foobar : public Baz {
      public:
        int extra; // public for demonstration purposes
    
        // Copy constructor takes care of actual copying
        Foobar(const Foobar& rhs) : Baz(rhs), extra(rhs.extra) { }
    
        // clone() uses copy constructor to create identical instance.
        // Note that the return type is Baz*, not Foobar*, so that inheritance works
        // as expected.
        virtual Baz* clone() const { return new Foobar(*this); }
    };
    
        2
  •  2
  •   mskfisher KeithS    15 年前

    你需要做 clone() 一个虚拟函数并在类中重写它 C ,像这样:

    class A
    {
    public:
        virtual A* clone() const  {  return new A(v1, v2);  }
    }
    
    class C : public A
    {
    public:
        virtual A* clone() const  {  return new C(v1, v2);  }
    }
    
        3
  •  1
  •   wkl    15 年前

    制作 clone() virtual和have子类B和C实现自己的版本 克隆() 并返回自己的新实例。

        4
  •  1
  •   Steve Jessop    15 年前

    其他答案没有什么特别的错误,但是如果我假设a的所有子类都可以 clone() Ed只是用两个参数构造,然后我会这样做:

    class A
    {
      public:
        A* clone() const  { return create(value1, value2); }
      private:
        virtual A* create(Type1 v1, Type2 v2) const { return new A(v1, v2); }
    };
    
    class C : public A
    {
        virtual C* create(Type1 v1, Type2 v2) const { return new C(v1, v2); }
    };
    

    如果没有别的,这意味着 value1 value2 在C类中不需要访问-它们可能是私有成员。如果它们是非平凡的表达式,那么它们也不需要在C中重复。

    不过,这是一个有点可疑的假设——你可能更希望 克隆() 使用派生类的复制构造函数,如tdammers的答案中所示。