Использование "new this.GetType()" в базовом классе для создания экземпляра производного класса

У меня есть базовый класс A, и классы B и C являются производными от него. A является абстрактным классом, и все три класса имеют конструктор, который принимает 2 аргумента. Можно ли сделать метод в базовом классе A следующим образом:

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

и если текущий объект, чья функция clone() вызывается, например, C, функция вернет указатель на новый объект класса типа C?

4 ответа

Решение

Это похоже на 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); }
};

Вам нужно сделать 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);  }
}

Ничего особенно плохого в других ответах, но если бы я предполагал, что все подклассы A могли бы быть clone()редактируемый просто с помощью двух параметров, я бы сделал это так:

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 - они могут быть частными членами. Если это нетривиальные выражения, их также не нужно повторять в Си.

Это немного сомнительное предположение, хотя - скорее всего, вы захотите clone() использовать конструктор копирования производного класса, как в ответе tdammers.

Делать clone() виртуальные и имеют подклассы B и C реализовать свою собственную версию clone() и вернуть новый экземпляр себя.

Другие вопросы по тегам