set::insert 是否保存副本或指针 C++ [英] Does set::insert saves a copy or a pointer C++

查看:51
本文介绍了set::insert 是否保存副本或指针 C++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

函数 set::insert 是否保存指向元素的指针或元素的副本.意思是,我可以做下面的代码,还是必须确保指针没有被删除?

does the function set::insert saves a pointer to the element or a copy of it. meaning, can I do the following code, or I have to make sure that the pointers are not deleted?

int *a;
*a=new int(1);
set<int> _set;
_set.insert (*a);
delete a;
*a=new int(2);
_set.insert (*a);
delete a;

我用 int 举例,但我的真实程序使用我创建的类.

I gave the example with int, but my real program uses classes that I created.

推荐答案

所有 STL 容器都存储插入数据的副本.查看此处第三段描述"部分:一个容器(和std::set 建模一个容器)拥有它的元素.有关更多详细信息,请查看以下脚注 [1].特别是对于 std::set这里在类型要求"部分下.Key 必须是可分配的.

All STL containers store a copy of the inserted data. Look here in section "Description" in the third paragraph: A Container (and std::set models a Container) owns its elements. And for more details look at the following footnote [1]. In particular for the std::set look here under the section "Type requirements". The Key must be Assignable.

除此之外,您还可以轻松测试:

Apart from that you can test this easily:

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);
}

你总会看到复制构造!.

如果你真的想存储一个对象的引用,你可以存储指向这些对象的指针:

If you really want to store something like a reference to an object you either can store pointers to these objects:

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.

But in this case you have to take care of deleting the objects correctly and this is sometimes very difficult. For example exceptions can change the path of execution dramatically and you never reach the right delete.

或者你可以使用像 boost::shared_ptr 这样的智能指针:

Or you can use smart pointers like 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.

现在智能指针会照顾您并在正确的时间删除它们引用的对象.如果您复制了其中一个插入的智能指针并将其转移到其他地方,则在引用此对象的最后一个智能指针超出范围之前,不会删除常用引用的对象.

Now the smart pointers takes care for you and delete their referenced objects at the right time. If you copied one of the inserted smart pointers and transfered it somewhere else the commonly referenced object won't be delete until the last smart pointer referencing this object goes out of scope.

哦,顺便说一句:从不使用 std::auto_ptrs 作为标准容器中的元素.它们奇怪的复制语义与容器存储和管理其数据的方式以及标准算法处理它们的方式不兼容.我相信 StackOverflow 上有很多关于这个不稳定问题的问题.

Oh and by the way: Never use std::auto_ptrs as elements in the standard containers. Their strange copy semantics aren't compatible with the way the containers are storing and managing their data and how the standard algorithms are manipulating them. I'm sure there are many questions here on StackOverflow concerning this precarious issue.

这篇关于set::insert 是否保存副本或指针 C++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆