从原始指针创建shared_ptr

Les*_*ieg 55 c++

我有一个指向对象的指针.我想将它存放在两个拥有所有权的容器中.所以我认为我很高兴它成为C++ 0x的shared_ptr.我怎么能将原始指针转换为shared_pointer?

typedef unordered_map<string, shared_ptr<classA>>MAP1;
MAP1 map1;
classA* obj = new classA();
map1[ID] = how could I store obj in map1??
Run Code Online (Sandbox Code Playgroud)

谢谢

Daw*_*son 41

您需要确保不使用相同的原始指针初始化两个shared_ptr对象,否则它将被删除两次.做得更好(但仍然很糟糕)的方法:

classA* raw_ptr = new classA;
shared_ptr<classA> my_ptr(raw_ptr);

// or shared_ptr<classA> my_ptr = raw_ptr;

// ...

shared_ptr<classA> other_ptr(my_ptr);
// or shared_ptr<classA> other_ptr = my_ptr;
// WRONG: shared_ptr<classA> other_ptr(raw_ptr);
// ALSO WRONG: shared_ptr<classA> other_ptr = raw_ptr;
Run Code Online (Sandbox Code Playgroud)

警告:上面的代码显示不好的做法!raw_ptr根本不应该作为变量存在.如果您使用结果直接初始化智能指针,则new可以降低意外初始化其他智能指针的风险.你应该做的是:

shared_ptr<classA> my_ptr(new classA);

shared_ptr<classA> other_ptr(my_ptr);
Run Code Online (Sandbox Code Playgroud)

有趣的是代码也更简洁.

编辑

我应该详细说明它如何与地图配合使用.如果你有一个原始指针和两个地图,你可以做一些类似于我上面显示的内容.

unordered_map<string, shared_ptr<classA> > my_map;
unordered_map<string, shared_ptr<classA> > that_guys_map;

shared_ptr<classA> my_ptr(new classA);

my_map.insert(make_pair("oi", my_ptr));
that_guys_map.insert(make_pair("oi", my_ptr));
// or my_map["oi"].reset(my_ptr);
// or my_map["oi"] = my_ptr;
// so many choices!
Run Code Online (Sandbox Code Playgroud)

  • 不要在变量中暴露原始指针.通过这样做,您可以让维护者更容易搞砸并将RAW指针放入另一个共享指针.只需使用`my_ptr(new ClassA());`这样一来,维护人员必须做额外的工作来搞砸了. (4认同)
  • 实际上,最佳实践是 make_shared&lt;&gt;,并且完全避免 new。我不记得深层原因,如果新投掷,我想是在肖恩·帕特尔的谈话中。 (3认同)

Kei*_*ith 6

您可以使用多种方式,但reset()会很好:

map1[ID].reset(obj);
Run Code Online (Sandbox Code Playgroud)

要解决两个映射引用同一个shared_ptr的问题,我们可以:

map2[ID] = map1[ID];
Run Code Online (Sandbox Code Playgroud)

请注意,避免双重删除的一般技巧是尽量避免使用原始指针.因此避免:

classA* obj = new classA();
map1[ID].reset(obj);
Run Code Online (Sandbox Code Playgroud)

而是将新的堆对象直接放入shared_ptr中.