【问题标题】:Proper way to initiate object on map在地图上启动对象的正确方法
【发布时间】:2018-07-18 21:30:03
【问题描述】:

我有一个 std::map,它有一个 int 作为键,一个对象指针作为值。在创建时,我应该先单独实例化对象,然后将它们插入容器中,还是可以直接在插入方法中调用“新”标签?除了简化代码之外,使用其中之一有什么好处吗?

map<int, Foo*> sample;

Foo* foo = new Foo();

sample.insert(pair<int, Foo*>(0, foo));       //case 1
sample.insert(pair<int, Foo*>(0, new Foo())); //case 2

【问题讨论】:

  • 两者都是正确的。取决于你以后是否想要foo。作为旁注,您不妨使用.emplace
  • 或者 sample[0] = new Foo(),这在语义上是不同的,但在这种情况下是等效的。
  • 案例 2 允许移动构造,但您使用的是指针,而指针移动的效率并不比它们在任何现实架构上复制的效率高。
  • 谢谢,伙计们。它澄清了它们都被接受,尽管适用于不同的情况。

标签: c++ dictionary object insert stdmap


【解决方案1】:

答案取决于程序中使用的对象所有权政策。

如果您希望动态分配对象的所有权属于sample,那么任何一种方法都可以。您必须确保在 sample 超出范围之前,其中包含的所有动态分配的对象都被删除。

如果您希望动态分配的对象的所有权不属于sample,那么第二种方法会导致内存泄漏,而第一种方法允许您在使用完对象后删除它。

您可以使用智能指针来管理动态分配对象的生命周期。然后,无论您使用哪种方法将对象添加到地图,您的代码都会变得更简单。例如

std::map<int, std::unique_ptr<Foo>> sample;
sample.insert(std::make_pair(0, std::make_unique<Foo>()));

【讨论】:

  • 我对这个问题的一个疑问就是“谁可以控制对象”,如果我们失去对事物的控制,这可能会很危险。感谢你的回答!它澄清了很多。
  • @JosneiLuisOlszewskiJunior,不客气。很高兴我能提供帮助。
  • 我建议使用 std::unique_ptr 而不是原始指针。维护对象的生命周期会更好。在您的示例中,您可能会泄漏新的指针。使用 make_unique. 而不是 new
猜你喜欢
  • 2019-11-22
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 2019-03-24
相关资源
最近更新 更多