C ++ - иметь тип, который может содержать своих детей

У меня есть связанный список типа Device:

Node<Device> list = new Node<device>(device);

И устройства имеют производные классы:

введите здесь описание изображения

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

Как мне это сделать?

Примечание. Если я отправлю Aerobic_Device в список, оно просто динамически преобразуется в Device, что приводит к потере данных.

ИЗМЕНИТЬ:

Я переделал всю логику своей программы для работы с указателями, и теперь список такой: Node<Device*> — Который все так же преобразует все в тип Device. Теперь, как многие предлагали, я переключил его на Node<std::unique_ptr<Device>>, но это только внесло много-много ошибок.


person Amit    schedule 28.12.2015    source источник
comment
Опубликовать содержимое класса/структуры Device/device.   -  person Richard Dally    schedule 28.12.2015
comment
Похоже, вам нужны умные указатели.   -  person Basile Starynkevitch    schedule 28.12.2015
comment
Вам нужен список указателей. Если это не домашнее задание, используйте стандартный контейнер.   -  person n. 1.8e9-where's-my-share m.    schedule 28.12.2015
comment
Вы можете сохранить идентификатор для каждого типа и определить его в устройстве: int getType(); чтобы получить этот идентификатор.   -  person Pierre Emmanuel Lallemant    schedule 28.12.2015
comment
Я думаю, что ваша проблема заключается в двух вещах: 1. Вам нужно сохранить указатель на Device в списке. 2. Вам понадобится общий интерфейс [или используйте dynamic_cast] с использованием виртуальных функций.   -  person Mats Petersson    schedule 28.12.2015
comment
Этот вопрос закрыт. Если у вас есть вопрос о хранении необработанных указателей или unique_ptrs в списке, задайте новый вопрос. Я рекомендую вам это сделать, потому что ваши замечания говорят о том, что вы плохо понимаете полиморфизм в C++.   -  person n. 1.8e9-where's-my-share m.    schedule 28.12.2015


Ответы (2)


Сделайте список типа Device* (обратите внимание на указатель).

Node<Device*> list;

Затем объявите объекты производных типов (PowerDevice, AerobicDevice, PowerAerobicDevice) и поместите их в список.

Таким образом, вы можете использовать возможности полиморфизма среды выполнения.

В качестве альтернативы вы можете (и должны) использовать интеллектуальные указатели вместо необработанных указателей для автоматической обработки памяти:

std::unique_ptr<Device> pDevice= std::make_unique<PowerDevice>(...);
// put into list
std::unique_ptr<Device> aDevice= std::make_unique<AerobicDevice>(...);
// put into list
std::unique_ptr<Device> paDevice= std::make_unique<PowerAerobicDevice>(...);
// put into list
person CinCout    schedule 28.12.2015
comment
Это ему не отвечает. Он хочет определить, какой подкласс используется, чтобы привести их для получения атрибутов. Он уже делает то, что вы говорите. - person Pierre Emmanuel Lallemant; 28.12.2015
comment
@PierreEmmanuelLallemant Можете ли вы прочитать код ОП? Потому что я не вижу этого в вопросе. - person juanchopanza; 28.12.2015
comment
juanchopanza: перечитайте вопрос. - person Pierre Emmanuel Lallemant; 28.12.2015

Вы не можете хранить свои объекты по значению и в то же время иметь полиморфное поведение. Вы можете хранить свои объекты с помощью (желательно умного) указателя:

Node<std::unique_ptr<Device>> list;
person el.pescado    schedule 28.12.2015
comment
Хорошо, почему бы не использовать обычные указатели? - person Amit; 28.12.2015
comment
@Amit Потому что умные указатели будут управлять памятью за вас, и это то, что вы должны использовать. - person Angew is no longer proud of SO; 28.12.2015
comment
Вы можете использовать обычный указатель, так как нет множественного наследования. - person Pierre Emmanuel Lallemant; 28.12.2015
comment
@Amit Если объектами владеет кто-то другой, можно использовать простые указатели. Но если список владеет ими или разделяет право собственности, вам нужен интеллектуальный указатель, который выражает эту модель владения. - person juanchopanza; 28.12.2015