【问题标题】:using "new this.GetType()" in a base class to instantiate a derived class在基类中使用“new this.GetType()”来实例化派生类
【发布时间】:2010-10-21 23:57:36
【问题描述】:

我有一个基类 A 和类 B 和 C 派生自它。 A 是一个抽象类,所有三个类都有一个带有 2 个参数的构造函数。是否可以像这样在基类A中创建一个方法:

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

如果当前正在调用其clone()函数的对象是C,该函数将返回指向C类类型新对象的指针?

【问题讨论】:

  • 这是托管 C++ 吗?我们的回应是针对标准 C++,尽管 tdammers 也讨论了托管部分。
  • 普通 C++,感谢所有答案 :)

标签: c++ class polymorphism


【解决方案1】:

这看起来像 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】:

您需要将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】:

    clone() 设为虚拟并让子类 B 和 C 实现它们自己的 clone() 版本并返回它们自己的新实例。

    【讨论】:

      【解决方案4】:

      其他答案没有什么特别的问题,但是如果我假设 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); }
      };
      

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

      不过,这有点可疑 - 您更可能希望 clone() 使用派生类的复制构造函数,就像 tdammers 的回答一样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-24
        • 2019-07-25
        • 2015-03-23
        • 2013-02-12
        • 2014-04-27
        • 2021-11-27
        • 2013-05-03
        • 1970-01-01
        相关资源
        最近更新 更多