Абстрактные классы

234
15 декабря 2016, 16:13

У меня есть абстрактный класс GeometryObjects и три класса наследника Point (точка), Line (2 точки), Polyline (список точек). Я создал список геометрических объектов:

list<GeometryObjects*> *a = new list<GeometryObjects*>;

А затем добавил в него определённым образом объекты типа Point, Line, Polyline. Сейчас мне необходимо получить доступ к некоторым полям объектов дочерних классов.

list<GeometryObjects*> *ls;
GeometryObjects* myGObj;
list<GeometryObjects*>::iterator it = ls->begin();
advance(it, index);
myGObj = *it;

Но у myGObj я могу вызывать только методы, описанные в абстрактном классе. Может, возможно как-то преобразовать GeometryObjects* в Point/Line/Polyline?

Answer 1

Смысл абстрактного класса Вашего типа - единообразная работа с разными объектами. Поэтому то, что Вы хотите - очевидно плохой паттерн. Теоретически, Вы можете добавить абстрактному классу метод "GetType", с, соответственно, разными реализациями у наследников, и создать класс GeometryControl с методом Invoke(GeometryObjects* go, GeometryType& type), который будет внутри себя вызывать dynamic_cast и преобразовывать указатель на родителя к указателю на ребенка. Но это плохой стиль.

В Вашем случае я бы отказался вообще от иерархии, сделайте класс GeometryObject не абстрактным, способным содержать в себе набор точек. И два класса: "Point" - точка и "Painter" - рисователь.

И храните список GeometryObject, имея прямой доступ до "внутренностей".

Одной реализации Painter хватит, чтобы рисовать и точку, и линию, и фигуру из линий. А вот для всяких эллипсов и прочая - придется делать другие реализации Painter-а (тут-то наследование и может пригодиться), которые и передавать в GeometryObject. Причем, я бы отказался от Painter, как базового абстракного для рисователей в пользу template<typename T> class Painter; с соответствующими реализациями метода Paint() для разного типа фигур (которые можно задавать пустыми типами class Square {}; class Ellipse {}; class Polyline {};

Это же позволит при конструировании класса Painter передавать ему радиус и другие settings, если надо.

READ ALSO
Связанные списки/linked lists

Связанные списки/linked lists

Изучаю сейчас самостоятельно связанные списки СКто-нибудь может сказать, почему, несмотря на то, что в последнем цикле while я вывожу лишь l1, l2 каким-то...

201
Получение полного пути к процессу по ID

Получение полного пути к процессу по ID

Имею ID процесса, отсюда могу найти его хендл, нужно найти полный путь к файлу, пока из примеров Майкрософт удалось только получить название...

265
Вставка кода Assembler-a

Вставка кода Assembler-a

Мне необходимо выставить значение 0xFFFE по адресу 0x80002040, я написал для этого такой код:

616