Как выделить память массиву экземпляров с помощью абстрактного класса?
У меня есть абстрактный класс, определяющий чистый виртуальный метод в c++:
class Base
{
Base();
~Base();
virtual bool Test() = 0;
};
Я подклассировал это с рядом других классов (которые предоставляют реализацию для Test ()), которые я буду называть A, B, C и т. д. Теперь я хочу создать массив любого из этих типов, используя этот базовый класс:
int main(int argc, char* argv[])
{
int size = 0;
Base* bases = new Base[10];
bases[size++] = new A();
bases[size++] = new B();
for (int i = 0; i < size; i++)
{
Base* base = bases[i];
base->Test();
}
}
(извините за любые ошибки, которые я мог бы сделать, я пишу это на лету, чтобы предоставить простой пример).
Проблема в том, что я не могу создать экземпляр массива, как это требуется создание экземпляра базового класса (что он не может сделать, так как он абстрактный). Однако без этого он не выделил память, необходимую для назначения индексов массива, и, таким образом, обеспечивает ошибку сегментации при попытке доступа к этой памяти. У меня сложилось впечатление, что смешивать new и delete с malloc и free-плохая практика.
Возможно, я перепутал способ, которым это должно использоваться, и я должен пытаться использовать шаблоны или какой-то другой механизм для этого. но, надеюсь, я предоставил достаточно информации, чтобы проиллюстрировать то, что я пытаюсь сделать.
Итак, как лучше всего это сделать и как обойти эту проблему выделения памяти абстрактному классу?
Спасибо,
Дан
3 ответов:
В этом коде есть только небольшое недоразумение. Вместо выделения базовых объектов необходимо выделить указатели. Указатель может существовать в любое время. Указатель на абстрактный класс, на неполный тип и даже на void допустим:
int main(int argc, char* argv[]) { int size = 0; Base** bases = new Base*[10]; bases[size++] = new A(); bases[size++] = new B(); for (int i = 0; i < size; i++) { Base* base = bases[i]; base->Test(); } }
Во-первых, убедитесь, что ваш деструктор также объявлен виртуальным:
virtual ~Base();Вам лучше хранить массив указателей на экземпляры:
Base** bases = new Base *[10];
Массив полагается на то, что все его элементы имеют одинаковый размер. Если у вас есть классы C++, производные от той же базы, экземпляры могут быть любого размера вообще. Таким образом, независимо от того, является ли база абстрактной или нет, вы не можете выделить массив базовых экземпляров, а затем поместить туда производные экземпляры.
Как говорят другие ответы, вам нужно использовать указатели. Выделите массив указателей на базу, а затем выделите различные производные экземпляры и сохраните указатель на них в массиве.
Comments