好的设计?用于分配的智能指针与用于访问的原始指针相结合
Good design? Smart pointers for allocation combined with raw pointers for access
我正在设计一个 FilterData
class 读取自定义二进制数据文件并在内存中构建它的数据模型。我想使用智能指针分配所有内存,让这个 FilterData
拥有数据的所有权。当调用者需要访问数据时,它只会从 FilterData
实例中获取原始指针。
您认为这是好的设计吗?或者作为程序员您会觉得 "mixture" 令人困惑吗?
一些想法:
为什么使用原始指针? 我需要与使用原始 float*
的现有 API 进行交互。此外,我强调调用者不拥有分配的内存。我的大多数 "clients" 都是在处理智能指针方面经验不足的编码人员。
如果我需要一份数据的副本,我可以用 return std::unique_ptr
的副本扩展 FilterData
相应的功能(因此转移所有权副本)。
作为一个可能的危险,我看到有人可以在 returned 指针上调用 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 但不要公开它或访问它的方法。你做到了,对你很好。公开原始指针,根据需要进行构造,如果有人想对其调用 delete,嘿,他们瞄准的是他们的脚。我宁愿以一种需要更少输入的方式公开原始指针。
2014 年 CPP Con 的这段演讲指出了这一点:https://youtu.be/xnqTKD8uD64?t=12m10s(我知道链接是邪恶的,但我怀疑这个链接会一直存在到自由女神像齐胸深的沙子中。)
我正在设计一个 FilterData
class 读取自定义二进制数据文件并在内存中构建它的数据模型。我想使用智能指针分配所有内存,让这个 FilterData
拥有数据的所有权。当调用者需要访问数据时,它只会从 FilterData
实例中获取原始指针。
您认为这是好的设计吗?或者作为程序员您会觉得 "mixture" 令人困惑吗?
一些想法:
为什么使用原始指针? 我需要与使用原始
float*
的现有 API 进行交互。此外,我强调调用者不拥有分配的内存。我的大多数 "clients" 都是在处理智能指针方面经验不足的编码人员。如果我需要一份数据的副本,我可以用 return
std::unique_ptr
的副本扩展FilterData
相应的功能(因此转移所有权副本)。作为一个可能的危险,我看到有人可以在 returned 指针上调用
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 但不要公开它或访问它的方法。你做到了,对你很好。公开原始指针,根据需要进行构造,如果有人想对其调用 delete,嘿,他们瞄准的是他们的脚。我宁愿以一种需要更少输入的方式公开原始指针。
2014 年 CPP Con 的这段演讲指出了这一点:https://youtu.be/xnqTKD8uD64?t=12m10s(我知道链接是邪恶的,但我怀疑这个链接会一直存在到自由女神像齐胸深的沙子中。)