所有 STL 容器都存储插入数据的副本。在第三段的“描述”部分查看here:一个容器(和std::set 模拟一个容器)拥有它的元素。有关更多详细信息,请查看以下脚注 [1]。特别是对于std::set,请在“类型要求”部分下查看here。 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_ptrs 用作标准容器中的元素。它们奇怪的复制语义与容器存储和管理数据的方式以及标准算法如何操作它们的方式不兼容。我敢肯定 StackOverflow 上有很多关于这个不稳定问题的问题。