C++:转向unique_ptr

3

我的问题是我是前端开发人员,但我需要对C++项目进行更改。

所以原来的情况是这样的:

std::vector<myObject*> myArray;
...
myArray.push_back(new myObject);
...
myArray.back();

我如何尝试改变它:

std::vector<std::unique_ptr<myObject>> myArray;
...
myArray.push_back(std::unique_ptr<myObject> (new myObject));
...
myArray.back().get(); // this place looks not good in my opinion :)

很多函数应该得到myObject*。而且我不知道如果我改变函数的参数会有多少变化。

请问您如何在这种情况下正确获取指针?


1
你打算如何处理向量中的最后一个元素?如果你只是想在其中调用一个函数,那么你可以这样做:myArray.back()->someFunctionInMyObject(); - Some programmer dude
7
你有存储指针而不是对象的充分理由吗? - juanchopanza
@Scheff,不会有复制和移动std::unique_ptr,所以在这种情况下它非常便宜。我认为这与此无关。 - Slava
@Scheff,就像我说的那样,你无法复制 std::unique_ptr,所以如果 push_back() 不能移动它,代码将无法编译。 - Slava
1
@juanchopanza,我的经理给了我这个问题。这是一个好的理由吗? :) - Lola
显示剩余4条评论
1个回答

10
如评论所述,您应该使用

myArray.push_back(std::make_unique<myObject>());

在大多数情况下,应该使用emplace_back而不是push_back,而不是new。应尽可能避免直接使用new

您不应经常调用.get()来访问std::unique_ptr中存储的对象。

您可以使用*获取对存储对象的引用:

auto& reference_to_object = *myArray.back();

您可以直接通过->访问成员:

myArray.back()->some_function();

只有在你需要一个非拥有指针(这应该比引用更少见)时,才需要调用.get()

auto ptr_to_object = myArray.back().get();

或者你可以使用

auto ptr_to_object = &*myArray.back();

除非在极少数情况下operator&被重载了,否则这不会发生在myObject中。


我认为问题在于你说的"很多函数应该获得myObject*"。这种情况应该比你所说的要少得多。只有那些可以接受空指针作为参数的函数才应该将指针作为参数传递,否则应优先考虑使用引用。前者并不经常发生。


此外,请注意您确实应该有一个很好的理由在std::vector内部使用(智能)指针。有几个原因不使用它们,例如myObject不能移动,移动成本非常昂贵,正在使用多态的myObject或需要引用被包含对象的元素来保证在添加/删除元素时不会失效。 (尽管在后一种情况下,std::list可能更好。)如果没有这些情况,或者我忘记提到的其他原因,则只需使用std::vector<myObject>即可。


很遗憾,我不能使用make_unique。我不够勇敢去将C++11改为C++14。抱歉忘了提到这一点。 - Lola
非常感谢您提供完整的答案。那么emplace_back更好吗?它会像这样 - myArray.emplace_back(new myObject)?这是安全的吗? - Lola
无论你使用 emplace_back 还是 push_back 在这里都无所谓。但不应该使用 new。使用 myArray.emplace_back(std::make_unique<myObject>()) 或者 myArray.push_back(std::make_unique<myObject>())。它们几乎执行完全相同的操作。 - walnut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接