【问题标题】:Use unique_ptr<std::vector> in combination with c-style arrays将 unique_ptr<std::vector> 与 c 样式数组结合使用
【发布时间】:2025-12-11 15:15:01
【问题描述】:

问题

我有一个处理图像的旧代码库。 C++ 风格很旧(在 C++11 之前),没有智能指针或类似的东西。只有很多动态分配和原始指针。

始终只处理一张实际图像。这些图像作为 c 样式数组保存和传递:

class A {
    A(double* image);
}

class B {
    B(){ image = new double[10]; };
    double* image;
} 

class C {
    C();
    foo(double* image);
}

我需要添加一个管理和读取图像的新类。我想建立一个这样的类,因为我对所有这些动态分配感到很不舒服,并且想使用更现代的 C++。

class NewImage {
     NewImage();
     double* getImage() { return &image.get()->at(0); };
     readImage();
     ...
private:
     std::unique_ptr<vector<double>> image;
}
  1. 是否推荐有getImage()这样的功能,用于将图像移交给旧部分?或者我应该使用std::unique_ptr&lt;double&gt; image 之类的东西吗?
    • 如果我使用std::unique_ptr&lt;double&gt; image,我是否需要一个自定义删除器,因为 unique_ptr 管理一个数组,而不是指向 double 的指针?
  2. 或者我不应该使用现代 C++ 并坚持旧风格吗?使用double* image 和动态分配?

【问题讨论】:

  • 很少,如果有的话,需要一个指向向量的指针。有时可能需要一个指针向量,但这似乎不是这种情况。你所需要的只是一个普通的向量。
  • 在此代码的 C++ 实现中不需要指针。为了节省开销,函数通过引用获取向量。如果您需要将向量赋予另一个对象,那么您可以使用移动语义来移动它,这样您就没有复制成本。
  • 扩展@Someprogrammerdude 的评论:很难证明std::unique_ptr&lt;std::vector&gt; 的合理性,因为与std::vector&gt; 相比,使用它基本上没有额外的好处(除了它可能是可空的)。但std::shared_ptr&lt;std::vector&gt; 的用例更常见。
  • @NathanOliver “这段代码的 C++ 实现”是什么意思? A、B 和 C 不能更改,这意味着要重新编写整个应用程序。我需要一个 NewImage 和旧功能之间的接口,它只接受 double*。
  • @Someprogrammerdude 我想使用 unique_ptr 来证明 NewImage 是此图像数据的所有者并为整个应用程序管理它。其他人一定不能将其设置为另一个图像。我想禁止来自某个地方的人添加 setter 并覆盖实际图像。

标签: c++ arrays unique-ptr class-design


【解决方案1】:

是否推荐有这样的getImage()函数将图像交给旧部分?

如果你有使用这样的功能,那么当然。更现代的替代方法可能是返回一个 span,它封装了指向开头的指针以及数组的长度。

或者我不应该使用现代 C++ 并坚持旧风格吗?使用双*图像和动态分配?

动态分配仍用于较新的设计。它只是隐藏在std::vector 中。

请注意,std::vector 从一开始就在 C++ 标准中,并且在没有容器的情况下管理动态数组是非常古老的风格,早于标准 C++(现在已有二十多年的历史)和之前的 STL。我不知道保留旧样式的好理由。


附:使用std::unique_ptr 的附加间接性可能没有任何优势。直接将向量存储为成员可能更理想。

【讨论】: