首页 > 解决方案 > 如何在 C++11 中设计数组类型的智能指针

问题描述


这是一个包含图像数据的类。

class MyMat
{
public:
    int width, height, format;
    uint8_t *data;
}

我想设计带有自动内存管理的 MyMat。图像数据可以在许多对象之间共享。我将要设计的常用 API:

+) C++ 11

+) 作业:共享数据

MyMat a2(w, h, fmt);
.................
a2 = a1; 

+) 访问数据应该简单而简短。可以直接使用原始指针。

一般来说,我想像 OpenCV cv::Mat 一样设计 MyMat

你能给我推荐一个合适的设计吗?

1) Using std::vector<uint8_t> data
我必须编写一些代码来删除复制构造函数和赋值运算符,因为有人可以调用它们并导致内存复制。编译器必须支持复制省略和返回值优化。总是使用移动赋值和通过引用传递是不方便的

a2 = std::move(a1)
void test(MyMat &mat)
std::queue<MyMat> lists;
lists.push_back(std::move(a1))
..............................

2) Use share_ptr<uint8_t> data
按照这个指南http://www.codingstandard.com/rule/17-3-4-do-not-create-smart-pointers-of-array-type/,我们不应该创建数组类型的智能指针。

3) Use share_ptr< std::vector<uint8_t> > data
访问数据,使用*(a1.data)[0],语法很不方便

4) Use raw pointer, uint8_t *data
为此类编写适当的构造函数和析构函数。要进行自动内存管理,请使用智能指针。

share_ptr<MyMat> mat
std::queue< share_ptr<MyMat> > lists;

标签: c++11smart-pointers

解决方案


std::array- 固定长度的就地缓冲区(美化数组)
std::vector- 可变长度的缓冲区
std::shared_ptr- 共享所有权数据
std::weak_ptr- 共享数据的过期视图
std::unique_ptr- 唯一所有权
std::string_view, std::span, std::ref, &, *- 对不假设所有权的数据的引用

最简单的设计是拥有一个单一的所有者和 RAII 强制生命周期,以确保在特定时间需要活着的所有东西都是活着的并且不需要其他所有权,所以通常我会在进一步复杂化之前看看我是否可以活着std::unique_ptr<T>(除非我能适应我所有的数据都在堆栈上,那么我什至不需要unique_ptr)。

附带说明 - 共享指针不是免费的,它们需要为共享状态分配动态内存(如果执行不正确,则分配两次 :)),而唯一指针是真正的“零”开销 RAII。


推荐阅读