好的设计?用于分配的智能指针与用于访问的原始指针相结合

Good design? Smart pointers for allocation combined with raw pointers for access

本文关键字:用于 指针 原始 相结合 访问 分配 智能      更新时间:2023-10-16

我正在设计一个FilterData类,它可以读取自定义二进制数据文件并在内存中构建它的数据模型。我想使用智能指针分配所有内存,并让这个FilterData拥有数据的所有权。当调用方需要访问数据时,它只会从FilterData实例获取一个原始指针。

你认为这是好的设计,还是作为程序员会觉得这种"混合"令人困惑?

一些想法:

  1. 为什么是原始指针?我需要与使用原始float*的现有 API 进行交互。此外,我强调调用方不拥有分配的内存。我的大多数"客户"都是编码人员,他们在处理智能指针方面没有经验。

  2. 如果我需要数据的副本,我可以使用相应的函数扩展FilterData,这些函数返回带有副本std::unique_ptr(因此转移副本的所有权)。

  3. 作为一个可能的危险,我看到有人可能会在返回的指针上调用delete,但由于我计划使用智能指针进行所有内存分配,因此无论如何任何delete都是错误的。

下面是一些示例代码:

#include <iostream>
#include <vector>
#include <string>
#include <memory>
class FilterData
{
using fvec = std::vector<float>;
public:
FilterData(const std::string& filename) {
// (simulate read from file...)
m_filterACoeffs = std::make_unique<fvec>();
m_filterBCoeffs = std::make_unique<fvec>();
m_filterACoeffs->emplace_back(1.f); m_filterACoeffs->emplace_back(2.f); m_filterACoeffs->emplace_back(3.f);
m_filterBCoeffs->emplace_back(-1.f); m_filterBCoeffs->emplace_back(-2.f); m_filterBCoeffs->emplace_back(-3.f);
}
const fvec* getFilterACoeffs() { return m_filterACoeffs.get(); }
const fvec* getFilterBCoeffs() { return m_filterBCoeffs.get(); }
private:
std::unique_ptr<fvec> m_filterACoeffs;
std::unique_ptr<fvec> m_filterBCoeffs;
};
int main() 
{
FilterData filterData("thefile.bin");
auto p_filterACoeffs = filterData.getFilterACoeffs();
auto p_filterBCoeffs = filterData.getFilterBCoeffs();
std::cout << "Filter A is: " << p_filterACoeffs->at(0) << " , " 
<< p_filterACoeffs->at(1) << " , " 
<< p_filterACoeffs->at(2) << std::endl; 
std::cout << "Filter B is: " << p_filterBCoeffs->at(0) << " , " 
<< p_filterBCoeffs->at(1) << " , " 
<< p_filterBCoeffs->at(2) << std::endl; 
}

在所有权被转让时使用并公开unique_ptr。当所有权是公共所有权时,请使用shared_ptr。定义函数以采用原始指针或引用,如果它们不参与所有权。

在您的情况下,请使用unique_ptr但不公开它或访问它的方法。你做到了,对你太好了。暴露原始指针,必要时进行修改,如果有人想在上面调用删除,嘿,这是他们的脚。我宁愿以需要较少键入的方式公开原始指针。

CPP Con 2014的这个演讲一针见血:https://youtu.be/xnqTKD8uD64?t=12m10s(我知道链接是邪恶的,但我怀疑这个链接会一直活到自由女神像深的沙子里。