我有一个名为X(例如)的类和一个公共函数toBytes(),它返回该对象的一些自定义二进制表示。
我的问题是:我应该如何返回这个字节数组?
目前,我有这个:
uint8_t* X::toBytes()
{
uint8_t* binData = new uint8_t[...];
// initialize the byte array
return binData;
}
这个问题(或者我作为一个没有经验的c ++程序员所考虑的问题)是,它在堆上分配内存,应该在某些我认为不实用的地方释放。要么类X应该以一些繁琐的方式在它的析构函数中释放这个内存,要么调用者应该释放它。调用者应该如何知道它是否有责任释放内存?它甚至不知道它是否是堆内存,对吧?
有点卡在这里:/
修改
我只想到了一个可能的解决方案:让调用者提供内存,就像指向字节数组的指针一样,并初始化该数组。这样可以解决问题,对吧?
答案 0 :(得分:4)
我将提供一个通用解决方案和一个便利包装器:
#include <iterator>
#include <vector>
template <typename OutIter>
void writeBytes(OutIter iter)
{
for (...) { *iter = data(); ++iter; }
}
std::vector<uint8_t> toBytes()
{
std::vector<uint8_t> result;
writeBytes(std::back_inserter(result));
return result;
}
通用版本允许用户与他们选择的任何类型的容器交互,方便的“矢量”版本允许用户编写类似for (auto b : toBytes())
的内容。
答案 1 :(得分:3)
假设在编译时不知道数组的大小,请使用std::vector
并返回它:
std::vector<uint8_t> toBytes()
{
std::vector<uint8_t> binData = ....;
return binData;
}
如果在编译时知道大小,那么您可能更喜欢使用std::array
:
std::array<uint8_t, 42> toBytes()
{
std::array<uint8_t, 42> binData = ....;
return binData;
}
答案 2 :(得分:1)
std::vector
方法很可能是首选方法。另一种方法是返回std::unique_ptr
:
std::unique_ptr<uint8_t[]> toBytes()
{
std::unique_ptr<uint8_t[]> result(new uint8_t[size]);
// ...
return result;
}
只有在某些限制导致您无法使用std::vector
时,这才有用。