Указатель на массив базового класса, заполненный производным классом

Если у меня есть базовый класс, только виртуальные методы и 2 производных класса от
базовый класс, с этими виртуальными методами реализованы.

Как я:

 // causes C2259
BaseClass* base = new BaseClass[2];

BaseClass[0] = new FirstDerivedClass;
BaseClass[1] = new SecondDerivedClass;

или же:

// causes "base is being used without being initialized"BaseClass* base;
// causes CC59 again
BaseClass* base = new BaseClass;

base[0] = FirstDerivedClass();
base[1] = SecondDerivedClass();

(или что-то подобное)

…так что я могу получить доступ к BaseClassметоды через DerivedClass,
но указатель и указатель является массивом DerivedClasss?

9

Решение

Ваш массив имеет неправильный тип: он хранит BaseClass объект экземпляры вместо указатели им. поскольку BaseClass кажется абстрактным, компилятор жалуется, что не может создавать экземпляры по умолчанию для заполнения вашего массива.

Даже если BaseClass не были абстрактными, использование массивов полиморфно является большой нет-нет в C ++, поэтому вы должны делать вещи по-другому в любом случае.

Исправьте это, изменив код на:

BaseClass** base = new BaseClass*[2];

BaseClass[0] = new FirstDerivedClass;
BaseClass[1] = new SecondDerivedClass;

Тем не менее, большую часть времени предпочтительнее использовать std::vector вместо простых массивов и умных указателей (таких как std::shared_ptr) вместо тупых указателей. Использование этих инструментов вместо написания кода вручную будет прозрачно решать множество проблем при крайне небольших затратах времени выполнения.

8

Другие решения

Это использование C ++ std::vector вместо простого массива:

std::vector<BaseClass*> base;
base.push_back(new FirstDerivedClass());
base.push_back(new SecondDerivedClass());

Как Kerrek SB заметил, что самый безопасный метод заключается в использовании std::unique_ptr:

std::vector<std::unique_ptr<BaseClass> > base;
base.push_back( std_unique_ptr<BaseClass>(new FirstDerivedClass()) );
base.push_back( std_unique_ptr<BaseClass>(new SecondDerivedClass()) );
3

Если ваш BaseClass содержит чисто виртуальные методы, это не удастся скомпилировать:

BaseClass* base = new BaseClass[2];

Если этого не произойдет, вы получите утечку памяти.

В c ++ это делается с помощью std :: vector или std :: array с неким умным указателем. Например :

std::vector< std::shared_ptr< BaseClass > > arr( 2 );
arr[0].reset( new FirstDerivedClass() );
arr[1].reset( new SecondDerivedClass() );
2

Это был ответ (от Рубби)

BaseClass* Base[2];

Base[0] = new FirstDerivedClass;
Base[1] = new SecondDerivedClass;
0

Определите массив указателей, тип указателя — BaseClass.
И назначить указатель на производный класс для элементов массива.
как:

BaseClass* base [2];
base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;
0
По вопросам рекламы [email protected]