Как создать динамический массив абстрактного класса? - PullRequest
13 голосов
/ 27 апреля 2010

Допустим, у меня есть абстрактный класс Cat, который имеет несколько конкретных подклассов Wildcat, Housecat и т. Д.

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

Когда я пытаюсь динамически выделить массив Cat, он, похоже, не работает.

Cat* catArray = new Cat[200];

Ответы [ 4 ]

19 голосов
/ 27 апреля 2010

Создавая ряд указателей для Cat, как в

 Cat** catArray = new Cat*[200];

Теперь вы можете поместить свои экземпляры WildCat, HouseCat и т. Д. В различные места массива, например

 catArray[0] = new WildCat();
 catArray[1] = new HouseCat();
 catArray[0]->catchMice(); 
 catArray[1]->catchMice();

Несколько предостережений, когда закончите
a) Не забудьте удалить экземпляры, размещенные в catArray, как в delete catArray [0] и т. д.
б) Не забудьте удалить сам catArray, используя

 delete [] catArray;

Вам также следует подумать об использовании вектора для автоматизации б) для вас

6 голосов
/ 27 апреля 2010

Вам нужно создать массив указателей на Cat:

Cat** catArray = new Cat*[200];

Даже если бы базовый класс Cat был конкретным, вы бы все равно пошли на нарезку объектов , если бы создали массив Cat.

Обратите внимание, что вы, вероятно, должны использовать std::vector вместо массива и, вероятно, должны использовать умные указатели, чтобы гарантировать, что ваш код безопасен от исключений.

4 голосов
/ 27 апреля 2010

Вы не можете округлять кошек в клетках фиксированного размера, потому что компилятор не может ни знать, насколько большими будут кошки, ни (из-за сбоя метафоры) как их инициализировать. Вам нужно что-то сделать, например, инициализировать массив нулевыми указателями кота или что-то в этом роде, а затем объединить их в стаду.

0 голосов
/ 27 апреля 2010

Вы не можете напрямую создать экземпляр экземпляра абстрактного класса, но вместо этого должны создать экземпляр полностью реализованного подкласса.

Так что это законно:

Housecat* theCats = new Housecat[200];

и затем вы можете получить доступ к каждой кошке через интерфейс Cat

bool catsMeow = ((Cat*)(&theCats[0]))->CanMeow();

Но у компилятора нет возможности узнать, как создать экземпляр абстрактного класса; фактически тот факт, что он абстрактный, означает, что его нельзя непосредственно создать.

Зачем это? Потому что у Cat будет абстрактный метод

bool CanMeow() = 0;

Это должны реализовать все унаследованные кошки. Тогда вы можете спросить, может ли он мяукать, и есть вероятность, что экземпляр Льва вернет ложь.

...