c++ - 你可以使用deleter的成员来保持shared_ptr的事件吗?

标签 c++ shared-ptr value-type

给定以下类型

// interface and implementation used in one part of the codebase
struct Image
{
    virtual std::vector<uint8_t>& GetData () = 0;
};

struct VecImage : public Image
{
    std::vector<uint8_t> mData;

    std::vector<uint8_t>& GetData () { return mData; }
};

// used in another part of the codebase
struct PtrImage
{
    std::shared_ptr<uint8_t> mData;

    PtrImage (std::shared_ptr<Image> pIm);
};

以下构造函数是将 Image 转换为 PtrImage 的合理且正确的方法吗?

PtrImage::PtrImage (std::shared_ptr<Image> pIm)
{
    struct im_deleter
    {
        std::shared_ptr<Image> keepAlive;
        void operator () (uint8_t* ptr)
        {
            keepAlive.reset ();
        }
    };

    mData = { &pIm->GetData()[0], im_deleter { pIm } };
}

PtrImage 用作“值类型”,它通过值传递,而 Image 仅在共享指针中传递。

最佳答案

is the following constructor a sane..

您延长 Image 的生命周期感谢析构函数,所以 data仍然有效。 所以你在这一点上是正确的......

但是, vector 可能会重新分配,从而使缓冲区无效。

因此生成的代码是不安全的。

您可以存储std::shared_ptr<std::vector<uint8_t>> mData;为了安全起见。

.. and correct way

我们有更好/更简单的别名构造函数 std::shared_ptr :

struct PtrImage
{
    std::shared_ptr<std::vector<uint8_t>> mData;

    PtrImage (std::shared_ptr<Image> pIm) : mData(pIm, &pIm->GetData()) {}
};

所以所有权信息PtrImage::mDatapIm 共享.

注意:我假设 GetData() 返回 vector 具有与 Image 相同(或更长)的生命周期(至于VecImage)。如果它是一个不相关的 vector (来自其他对象),那么你将没有解决方案。

正如评论中所述, vector 也不应该重新分配

关于c++ - 你可以使用deleter的成员来保持shared_ptr的事件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56164162/

相关文章:

c++ - 没有 ExecutionPolicy 的 std::transform 或 std::generate 可以并行吗?

c++ - 完全线程安全的 shared_ptr 实现

c++ - 如何在 C++ 中创建良好的上下文类/返回引用?

c# - 什么时候使用 C# 结构(值类型)会牺牲性能?

c++ - 这段代码是线程安全的吗?

c++ - vector 和函数练习

c++ - flann/util/serialization.h 类 std::unordered_map<unsigned int, std::vector<unsigned int>>' has no member named ' 序列化'

c++ - 使用值为 std::shared_ptr 的映射是否是具有多索引类列表的良好设计选择?

c# - 为什么我可以检查 DateTime 是否为 null,即使它是一个值类型?

c# - .net - 锁定盒装值而不是新对象