stl vector.push_back () абстрактный класс не компилируется - PullRequest
3 голосов
/ 10 августа 2009

Допустим, у меня есть вектор stl, содержащий тип класса "xx". хх абстрактно. Я столкнулся с проблемой, когда компилятор не позволяет мне «создавать экземпляры», когда я делаю что-то вроде следующего:

std::vector<xx> victor;
void pusher(xx& thing)
{
    victor.push_back(thing);
}

void main()
{
    ;
}

Я предполагаю, что это потому, что должен быть вызван конструктор копирования. Я обошел эту проблему, храня xx * в векторе, а не в xx. Есть ли лучшее решение? Что это?

Ответы [ 3 ]

12 голосов
/ 10 августа 2009

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

Рекомендуется использовать указатель или один из многих типов интеллектуальных указателей, доступных в библиотеках, таких как boost и loki .

2 голосов
/ 10 августа 2009

Чтобы быть более католиком, чем Папой Римским (или в данном случае Стивом Гвиди), требования к объектам, хранящимся в контейнерах STL, заключаются в том, что они могут быть созданы и назначены для копирования, а абстрактный класс - ни то, ни другое Таким образом, в этом случае контейнер указателей - это путь. Еще одна вещь, которую следует учитывать в случае, если вы решите исправить ситуацию, не делая абстрактные классы, будут slicing .

0 голосов
/ 10 августа 2009

std :: vector (и весь STL в целом) предназначен для хранения значений. Если у вас есть абстрактный класс, вы не намерены манипулировать значением этого типа, а манипулировать указателем или ссылками на него. Так что иметь std :: vector абстрактного класса не имеет смысла. И даже если он не является абстрактным, обычно не имеет смысла манипулировать классом, предназначенным для использования в качестве базовых классов, в качестве значения, они обычно должны быть не копируемыми (конструктор копирования и оператор присваивания, объявленные как частные и не реализованные, являются стандартным приемом, наследующим от подходящий класс, единственная цель которого - сделать его потомка не копируемым (например, boost :: noncopyable - стал fashionanle).

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