c++ - 在范围内保持 shared_ptr

标签 c++ c++11 shared-ptr

我有一个类处理一组共享指针并将它们存储在各种(互斥)集合中。该类的任务之一是在添加/删除其中一个共享指针时使这些容器保持最新。

为了便于维护这些集合,我有一些辅助函数可以对共享指针进行分类,从所有关联的容器中添加/删除它,并执行任何其他必要的工作。这很好用除了,如果直接在容器的元素上调用 remove 函数,共享指针在函数完成之前被释放。

我通过按值将元素传递给函数解决了这个问题。这为函数提供了它自己的共享指针拷贝,并使其保持事件状态直到函数结束。我对这个解决方案很满意(并且对需求/动机进行了评论)但是这个函数不断被代码审计工具(例如 clang-tidy)标记/更改为性能不佳并更改为 const 引用。

如何避免这种情况?该函数只是更大库的一小部分,维护者遗漏注释是可以理解的。我无法更改代码审核规则,所以我想要一种简单有效的方法来避免这个问题?我怀疑 C++11 和 std::move 可能有一些聪明的东西?

举个例子,如果我的类(class)正在使用 FruitPtr共享指针,它可能有集合,例如,

std::vector<FruitPtr> greenFruit_;
std::vector<FruitPtr> redFruit_;
std::vector<FruitPtr> sweetFruit_;
std::vector<FruitPtr> sourFruit_;

等等

有问题的函数看起来像

removeFruit(FruitPtr oldFruit)
{
    // Remove the element from any containers it belongs to:
    if (/*Some container condition*/)
    {
        //Find and remove from container
    }
    // etc., for all containers

    // Do some final operations on the element that must occur after it is removed from the containers,
    oldFruit->markSpoiled();
}

这很好用,但是如果将其更改为 removeFruit(const FruitPtr& oldFruit)然后当直接调用容器的元素时,例如 removeFruit(greenFruit_[i]) , 指针 oldFruit在对元素本身执行最终操作之前,一旦从所有容器中移除它,它就会被销毁。在我的库中,这些操作必须在函数结束时执行,因为它们会影响在容器中查找元素。

那么,我该如何让这个函数与 const 引用一起工作,或者让代码审计工具/阅读器清楚地知道它不能?

编辑 注意:

  • FruitPtrstd::shared_pointer<Fruit>
  • 指针的唯一拷贝可能位于 removeFruit 的容器中正在运行(假设它们是)。

最佳答案

我的直接解决方案是让该函数制作自己的拷贝,例如,

removeFruit(const FruitPtr& oldFruit)
{
    FruitPtr fruitToRemove(oldFruit)

    //...

    // Use fruitToRemove everywhere in the function, e.g.,
    fruitToRemove->markSpoiled();
}

但是还有更聪明的东西吗?有点像 C++11 中的 std::move

关于c++ - 在范围内保持 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38916730/

相关文章:

c++ - 已删除的默认构造函数被标识为歧义错误中的候选者

c++ - 是否有通过引用分配 shared_ptr 的用例?

c++ - 为什么指向成员的指针的值对于同一结构的不同成员总是相同的?

c++ - 使用 Boost Asio 套接字为双端队列调用移动构造函数时出现问题

c++ - 解析 VS2010 MSBuild vcxproj 文件

c++ - 如何解包类型定义的类型?

c++ - 尝试在 Linux 上使用 Clang++ 编译 c++11 正则表达式教程时出错

c++ - Boost::HPC 侵入式

C++11 Cereal 库无法序列化我的类

c++ - 多线程应用程序在内存使用率高时崩溃并出现错误 R6016 或 0xC0000005