Использование "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
, Обычные шаги:
- Создать или получить подходящий
Type
объект, например, путем вызоваGetType
, - Найти подходящий
ConstructorInfo
(Type.GetConstructors()
IIRC) - Вызов
ConstructorInfo.Invoke()
создать экземпляр - Бросить получившийся
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()
и вернуть новый экземпляр себя.