gpt4 book ai didi

具有引用计数的 C++ 指针容器

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:56:40 28 4
gpt4 key购买 nike

我需要一个集合,我可以在其中存储具有虚函数的堆分配对象。

我知道 boost::shared_ptrstd::unique_ptr (C++11) 和 boost::ptr_(vector|list|map) ,但它们并没有解决重复指针问题。

只是为了描述一个问题 - 我有一个函数接受堆分配的指针并将其存储以备将来使用:

void SomeClass::add(T* ptr)
{
_list.push_back(ptr);
}

但是如果我用相同的参数 ptr 调用 add 两次 - _list 将包含指向同一对象的两个指针,当 _list 被破坏会出现多次删除同一个对象。

如果 _list 将他存储的指针计数并在删除时使用它们,那么这个问题将得到解决,对象将不会被多次删除。

那么问题是:

有人知道一些带有指针集合(本质上是 vector 、列表、映射)的库,在销毁时自动删除并支持引用计数吗?

或者也许我可以使用其他技术解决这个问题?

更新:

我需要对重复指针的支持。所以我不能使用 std::set

作为Kerrek SBGrizzly提到 - 通常使用原始指针是个坏主意,建议使用 std::make_shared 并忘记通过 new 进行实例化。但这是客户端代码的责任——而不是我设计的类。即使我将 add 签名(当然还有 _list 容器)更改为

void SomeClass::add(std::shared_ptr<T> ptr)
{
_list.push_back(ptr);
}

然后有人(不知道 std::make_shared)仍然可以这样写:

SomeClass instance;
T* ptr = new T();
instance.add(ptr);
instance.add(ptr);

所以这不是我等待的完整解决方案,但如果您单独编写代码则很有用。

更新 2:

作为替代解决方案,我找到了克隆(使用生成的复制构造函数)。我的意思是我可以像这样更改我的 add 函数:

template <typename R>
void SomeClass::add(const R& ref)
{
_list.push_back(new R(ref));
}

这将允许虚方法(R - 扩展某些基类(接口(interface))的类)调用并禁止重复指针。但是这个解决方案对克隆有开销。

最佳答案

是:std::list<std::shared_ptr<T>> .

共享指针可从<memory>获得,或在来自 <tr1/memory> 的旧平台上,或来自 Boost 的 <boost/shared_ptr.hpp> .您不需要手动删除任何内容,因为共享指针会自行处理。但是,您需要从一开始就将所有您的堆指针保存在一个共享指针中:

std::shared_ptr<T> p(new T);    // legacy
auto p = std::make_shared<T>(); // better

如果您将另一个共享指针指向同一个对象,请复制共享指针(而不是从底层原始指针构造一个新的共享指针):auto q = p;


这里的寓意是:如果您使用的是裸指针,那就有问题了。

关于具有引用计数的 C++ 指针容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8774762/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com