从向量中按内存地址删除共享指针
Posted
技术标签:
【中文标题】从向量中按内存地址删除共享指针【英文标题】:Delete shared pointer by memory address from vector 【发布时间】:2020-10-16 23:05:14 【问题描述】:我有一个包含共享指针的向量。我想通过使用它的内存地址从列表中删除一个指针,这可能吗?或者有没有更好的方法来存储共享指针的集合?
std::vector<std::shared_ptr<Person>> list;
void removePerson(const std::shared_ptr<Person>& person)
auto remove = std::remove(list.begin(), list.end(), person);
list.erase(remove, list.end());
【问题讨论】:
“它的内存地址”是指指针的值(即shared_ptr指向的Person对象的内存位置),还是指针的地址(即shared_ptr的内存位置对象本身,位于向量的内部项目数组内)? 如果您想按值快速查找,std::set
或 std::unordered_set
将分别为您提供 O(log(N))
和 O(1)
查找时间,两者都比 O(N)
按值查找快得多std::vector
的时间(尽管只有当您维护的 shared_ptrs 数量很大时,性能差异才会明显,例如数百/数千或更多)
这不是调用list.erase
删除所有要删除的项目吗?
list.erase(remove);
应该被调用以从向量中删除单个项目。
这可能吗?你尝试的时候发生了什么?
【参考方案1】:
是的,可以按地址从指针容器中删除指针。
虽然std::vector<std::shared_ptr<T>>
是一种存储共享指针的普通方式,但如果不了解您的需求,就无法回答哪种方式更好的问题。
这是您模板的扩展,用于演示按地址删除指针,使用您自己的 removePerson()
函数:
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
// A minimal Person type for demonstration purposes
struct Person
Person(const std::string& n): name(n)
std::string name;
;
// Original template
std::vector<std::shared_ptr<Person>> persons;
void removePerson(const std::shared_ptr<Person>& person)
auto remove = std::remove(persons.begin(), persons.end(), person);
persons.erase(remove, persons.end());
int main()
auto bob = std::make_shared<Person>("bob");
// Include bob multiple times to demonstrate multiple removal
persons.emplace_back(bob);
persons.emplace_back(std::make_shared<Person>("alice"));
persons.emplace_back(bob);
persons.emplace_back(std::make_shared<Person>("carol"));
persons.emplace_back(bob);
// Define a lambda for debugging output
auto printPersons = [&] (const auto& header)
std::cout << header << std::endl;
for(auto& p: persons)
std::cout << p->name << std::endl;
;
printPersons("== Before ==");
removePerson(bob);
printPersons("\n== After ==");
这会产生以下输出:
== Before ==
bob
alice
bob
carol
bob
== After ==
alice
carol
注意:std::vector
通常不会命名为 list
,因为它不是一个列表;-)
【讨论】:
请注意,std::remove()
将扫描整个向量。如果指针仅在向量中存储一次,则应使用 std::find()
代替,然后使用 erase()
唯一的迭代器,如果它不是结束迭代器则返回。以上是关于从向量中按内存地址删除共享指针的主要内容,如果未能解决你的问题,请参考以下文章