c ++ связанный список — вставка объекта

У меня есть общий связанный список, который работает с различными типами данных, включая объекты и указатели на объекты и т. Д., Но у меня возникают проблемы при работе со списком, когда я вставляю объекты из класса, производного от абстрактный класс.

У меня есть абстрактный класс под названием vehicle и 2 класса carr и truck, и я могу сделать что-то вроде этого:

list<vehicle> lv;

vehicle * v1;
vehicle * v2;

v1 = new carr;
v2 = new truck;

cin >> *v1 >> *v2;

//But when I try to insert in the list

lv.insertEnd(*v1);

У меня ошибка:

не может выделить объект абстрактного типа «транспортное средство»

И компилятор показывает, что ошибка в методе insertEnd моего кода связанного списка в той части, где я пишу:

newNode->item = new Item;

Это часть проекта, где мне нужно иметь список транспортных средств, и транспортные средства могут быть легковыми автомобилями, грузовиками и т. Д. У меня есть группа транспортных средств, реализованная с указателями на указатели, но я пытаюсь сделать это с помощью списка транспортных средств. ,

Вы можете мне помочь?

РЕДАКТИРОВАТЬ:
Элемент находится в моем связанном списке, я покажу мой метод insertEnd:

template <class Item>
void list<Item>::insertEnd(const Item& item)
{
node<Item> *newNode= new node<Item>;

newNode->item = new Item;
*(newNode->item) = item;
newNode->next = 0;

if(head == 0)
{
head = newNode;
tail = newNode;
_size++;
}
else
{
novoNo->prev = tail;
tail->next = newNode;
tail = newNode;
_size++;
}
}

0

Решение

Вы пытаетесь сохранить элемент по значению в вашем связанном списке. Использование элементов по значению нарушает полиморфизм: только указатели или ссылки являются полиморфными.

Причина, по которой вы видите ошибку, состоит в том, что вы разыменовываете свой указатель здесь: lv.insertEnd(*v1), Передача значения таким образом заставит C ++ использовать конструктор копирования для типа, указанного в insertEnd сделать объект внутри вашего insertEnd функция (проверьте ваш код: тип параметра для insertEnd безусловно, тип, указанный в вашем шаблоне — который vehicle Вот). Передавая по значению, вы говорите свой код, чтобы скопировать весь v1 в новый объект внутри insertEnd, Это разваливается, потому что vehicle является абстрактным классом: его конструктор копирования нельзя использовать для создания полностью функционального объекта, потому что он абстрактный.

Такого рода тени скрывают то, что действительно происходит здесь: вы не можете передавать объекты по значению и ожидать, что они будут полиморфными. Если вы не видите эту ошибку, скорее всего, вы нарезать свой объект, что может быть еще хуже для отладки. Делайте то, что рекомендует @billz, и используйте умный указатель.

РЕДАКТИРОВАТЬ: после того, как вы добавили свой код insertEnd, по которому вы переходите по ссылке, есть дополнение: компилятор не собираюсь вызвать конструктор копирования в insertEnd, Вместо этого вы, вероятно, видите ошибку в этой строке: newNode->item = new Item, Здесь вы можете увидеть, где вы пытаетесь создать экземпляр абстрактного класса. Замени словоItem‘ с ‘vehicle«- это то, что вы делаете со своим шаблоном — и вы можете видеть это очень четко.

В любом случае передача по ссылке на разыменованный указатель действительно очень болезненная и подверженная ошибкам вещь. Слишком легко вводить ошибки: если вы delete v1 где-нибудь в вашем коде, как это делает хороший программист (великие используют автоматические указатели), вы, вероятно, оставите свою ссылку свисающей: указание на пространство в памяти, которое когда-нибудь — например, когда кто-то важный выполняет ваш код — может быть заполнено мусор без вашей ссылки, зная это. Это путь к безумию, друг мой.

Именно поэтому умные указатели — лучший друг программиста на C ++: как только вы Понимаю что бы они ни делали, вы можете просто игнорировать этот беспорядок и просто передавать их по значению свободно. Их контракт на жизненный цикл очень хорошо определен, они убирают за собой, они безопасны от исключений. Пока вы не настроите циклы ссылок — что гораздо менее проблематично в повседневном использовании, чем передача разыменованного указателя по ссылке — или попробуйте использовать auto_ptr в стандартном контейнере ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ ЭТУ ССЫЛКУ И ПОНИМАЙТЕ ЕГО, Вы значительно уменьшили свои проблемы с памятью.

5

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

в этом случае вам нужно использовать указатель, лучше использовать интеллектуальный указатель.

std::list<std::shared_ptr<vehicle> > lv;

В вашем list<vehicle> lv;, lv только содержит vehicle тип объекта, lv.insertEnd(*v1); будут ломтик Ваш объект относится к типу транспортного средства, что не разрешено, поскольку транспортное средство является абстрактным классом.

2

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

Кроме того, семантика конструкции копии stl не поддерживает полиморфное использование. список «ТС» должен содержать только объекты ТС, а не объекты ТС.

Вы должны использовать контейнер указателей.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector