Евгений Шатунов, это понятно. Под копированием имел в виду, что при передаче его в функции дважды выполнялась неявная конвертация его в std::list, с копированием всех данных. Это копирование и один-то раз делать жалко.
При создании cars стоит указать тип vector<Car>, иначе это будет initializer_list, который несколько раз (!) будет копироваться в нормальный контейнер. Ну и параметры нужно в большинстве случаев передавать в функцию по ссылке (кроме всяких int-ов и случаев, когда важно создание копии)
Евгений Шатунов, спасибо, добавил про виртуальный деструктор. (Что-то показалось, что Армянское Радио упоминал про это - ан нет.) Про порождающие шаблоны - в простейшем случае, когда непосредственно создаётся вектор из всех object-ов, это не нужно. Хотя шаблоны полезные, возможно, стоит описать их в собственном ответе.
shevzoom, часто при считывании строки последним символом вписывается \n. Решение такое: после считывания строки, если последний символ строки \n, то удалить последний символ строки.
std::list
, с копированием всех данных. Это копирование и один-то раз делать жалко.