использование "new this.GetType ()" в базовом классе для создания экземпляра производного класса - PullRequest
0 голосов
/ 22 октября 2010

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

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

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

Ответы [ 4 ]

2 голосов
/ 22 октября 2010

Вам нужно сделать 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);  }
}
2 голосов
/ 22 октября 2010

Это похоже на 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); }
};
1 голос
/ 22 октября 2010

Ничего особенно плохого в других ответах, но если бы я предполагал, что все подклассы 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.

1 голос
/ 22 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...