std::make_unique<Party>(something) 本质上等同于 std::unique_ptr<Party>(new Party(something)),所以是的,它正在创建 Party 对象的新副本,因为您要求它。
最终,unique_ptr 似乎不是正确的选择:如果您的 std::vector 已经是对象的唯一所有者(和生命周期的管理者),那么您不需要做任何特别的事情,您可以使用普通的指针/引用。但是请注意,它们的有效性与 std::vector 的引用失效规则相关 - 特别是,如果它决定重新分配(例如,如果您执行 push_back),所有指针/引用都将变为无效。
std::unordered_map<std::string, Party*> map_;
std::vector<Party> parties_;
parties_.emplace_back("AAA");
parties_.emplace_back("BBB");
parties_.emplace_back("CCC");
Party *ptr = &parties_.back();
// Notice: if you do parties_.emplace_back("DDD") here
// ptr may become invalid
ptr->value_ = "XXX";
for (auto& p : parties_) {
std::cout << p.value_ << std::endl; // print: AAA\nBBB\nXXX
}
如果您想与重新分配的影响隔离开来,但可以接受 std::vector 作为所有者,从而决定您的对象的生命周期,您可以拥有一个 std::vector<std::unique_ptr<Party>>(同样,保持简单指向它们的指针/引用)
std::unordered_map<std::string, Party*> map_;
std::vector<std::unique_ptr<Party>> parties_;
parties_.emplace_back(std::make_unique<Party>("AAA"));
parties_.emplace_back(std::make_unique<Party>("BBB"));
parties_.emplace_back(std::make_unique<Party>("CCC"));
Party *ptr = parties_.back().get();
// Notice: if you do parties_.emplace_back(std::make_unique<Party>("DDD"));
// ptr will remain valid
ptr->value_ = "XXX";
for (auto& p : parties_) {
std::cout << p.value_ << std::endl; // print: AAA\nBBB\nXXX
}
这确保对象是独立于向量分配的,但如果它们从向量中删除,它们将被删除。
OTOH,如果您想在矢量和地图之间共享所有权,您可能需要std::shared_ptr(但它不是免费提供的,它必须管理引用计数和 co。):
std::unordered_map<std::string, std::shared_ptr<Party>> map_;
std::vector<std::shared_ptr<Party>> parties_;
parties_.emplace_back(std::make_shared<Party>("AAA"));
parties_.emplace_back(std::make_shared<Party>("BBB"));
parties_.emplace_back(std::make_shared<Party>("CCC"));
std::shared_ptr<Party> ptr = parties_.back();
// Notice: if you do parties_.emplace_back(std::make_unique<Party>("DDD"));
// ptr will remain valid, but it will still be valid even after
// parties_.pop_back() (ptr will keep the pointed object alive)
ptr->value_ = "XXX";
for (auto& p : parties_) {
std::cout << p.value_ << std::endl; // print: AAA\nBBB\nXXX
}
这可确保对象的生命周期与向量的生命周期无关,因为原始 std::shared_ptr 的任何副本都将 (1) 指向同一个对象并 (2) 使其保持活动状态。