STL: хранит ссылки или значения?
Я всегда был немного смущен тем, как контейнеры STL (вектор, список, карта...) хранят значения. Сохраняют ли они ссылки на значения, которые я передаю, или они копируют/копируют конструкцию + сами хранят значения?
Например,
int i;
vector<int> vec;
vec.push_back(i);
// does &(vec[0]) == &i;
и
class abc;
abc inst;
vector<abc> vec;
vec.push_back(inst);
// does &(vec[0]) == &inst;
Спасибо
Ответы
Ответ 1
Контейнеры STL копируют и сохраняют значения, которые вы передаете. Если вы хотите хранить объекты в контейнере без их копирования, я бы предложил сохранить указатель на объект в контейнере:
class abc;
abc inst;
vector<abc *> vec;
vec.push_back(&inst);
Это наиболее логичный способ реализации классов контейнеров для предотвращения случайного хранения ссылок на переменные на несуществующих кадрах стека. Рассмотрим:
class Widget {
public:
void AddToVector(int i) {
v.push_back(i);
}
private:
vector<int> v;
};
Сохранение ссылки на i
было бы опасно, так как вы ссылались бы на расположение памяти локальной переменной после возврата из метода, в котором она была определена.
Ответ 2
Это зависит от вашего типа. Если это простой тип значения и дешевый для копирования, то сохранение значений, вероятно, является ответом. С другой стороны, если это ссылочный тип или дорогостоящий для копирования, лучше сохранить интеллектуальный указатель (а не auto_ptr, поскольку его специальная семантика копирования не позволяет хранить его в контейнере. Перейти к shared_ptr). С помощью простого указателя вы рискуете утечкой памяти и доступом к освобожденной памяти, а со ссылками вы рискуете последним. Умный указатель позволяет обойти оба.