Все контейнеры STL хранят копию вставленных данных. Посмотрите здесь в разделе «Описание» в третьем абзаце: Контейнер (и std::set
моделирует Контейнер) владеет своими элементами. А для более подробной информации смотрите следующую сноску [1]. В частности, для std::set
смотрите здесь в разделе "Типовые требования". Key
должен быть назначаемым.
Кроме того, вы можете легко проверить это:
struct tester {
tester(int value) : value(value) { }
tester(const tester& t) : value(t.value) {
std::cout << "Copy construction!" << std::endl;
}
int value;
};
// In order to use tester with a set:
bool operator < (const tester& t, const tester& t2) {
return t.value < t2.value;
}
int main() {
tester t(2);
std::vector<tester> v;
v.push_back(t);
std::set<tester> s;
s.insert(t);
}
Вы всегда увидите Copy construction!
.
Если вы действительно хотите сохранить что-то вроде ссылки на объект, вы можете хранить указатели на эти объекты:
tester* t = new tester(10);
{
std::set<tester*> s;
s.insert(t);
// do something awesome with s
} // here s goes out of scope just as well the contained objects
// i.e. the *pointers* to tester objects. The referenced objects
// still exist and thus we must delete them at the end of the day:
delete t;
Но в этом случае вы должны позаботиться о правильном удалении объектов, а это иногда очень сложно. Например, исключения могут радикально изменить путь выполнения, и вы никогда не достигнете права delete
.
Или вы можете использовать умные указатели, такие как boost::shared_ptr
:
{
std::set< boost::shared_ptr<tester> > s;
s.insert(boost::shared_ptr<tester>(new tester(20)));
// do something awesome with your set
} // here s goes out of scope and destructs all its contents,
// i.e. the smart_ptr<tester> objects. But this doesn't mean
// the referenced objects will be deleted.
Теперь умные указатели позаботятся о вас и удалят объекты, на которые они ссылаются, в нужный момент. Если вы скопировали один из вставленных интеллектуальных указателей и перенесли его в другое место, объект, на который обычно ссылаются, не будет удален, пока последний интеллектуальный указатель, ссылающийся на этот объект, не выйдет из области видимости.
Да, и кстати: Никогда не используйте std::auto_ptr
s в качестве элементов в стандартных контейнерах. Их странная семантика копирования несовместима с тем, как контейнеры хранят свои данные и управляют ими, и как стандартные алгоритмы манипулируют ими. Я уверен, что в StackOverflow есть много вопросов, касающихся этой нестабильной проблемы.