C++ 从C+;中的函数返回动态分配的缓冲区的最佳模式是什么+;?
我正在重构一些旧代码。有一个C风格的函数是这样工作的:(显然我在这里简化了它) 现在,我想更新这段代码,以某种方式返回一个唯一的\u ptr或等效值,这样指针将由调用者自动管理,调用者永远不会忘记释放内存 我找不到好的解决方案,因此目前我已将代码更改为以下内容:C++ 从C+;中的函数返回动态分配的缓冲区的最佳模式是什么+;?,c++,design-patterns,memory-management,unique-ptr,C++,Design Patterns,Memory Management,Unique Ptr,我正在重构一些旧代码。有一个C风格的函数是这样工作的:(显然我在这里简化了它) 现在,我想更新这段代码,以某种方式返回一个唯一的\u ptr或等效值,这样指针将由调用者自动管理,调用者永远不会忘记释放内存 我找不到好的解决方案,因此目前我已将代码更改为以下内容: int LoadData(std::unique_ptr<char[]>* ubuf1, int* buf1Len, std::unique_ptr<char[]>* ubuf2, int* buf2Len) {
int LoadData(std::unique_ptr<char[]>* ubuf1, int* buf1Len, std::unique_ptr<char[]>* ubuf2, int* buf2Len) {
// same code as above, and finally:
ubuf1->reset(buf1);
ubuf2->reset(buf2);
return result;
}
int-LoadData(std::unique_ptr*ubuf1,int*buf1Len,std::unique_ptr*ubuf2,int*buf2Len){
//代码同上,最后:
ubuf1->重置(buf1);
ubuf2->重置(buf2);
返回结果;
}
这看起来不太好,所以我想看看是否有更好的解决方案。因为我返回两个缓冲区,所以使用unique\u ptr
作为返回值不是一个选项
有更好的方法吗?如果不需要,请不要对数组使用
std::unique\u ptr
。存储动态数组的合适工具通常是std::vector
。它将大小信息与对象一起打包,对象位于该对象所属的位置。如果您的char*
被用作字符串,那么您可能需要使用std::string
std::pair<std::vector<char>, std::vector<char>>
LoadData()
{
std::vector<char> buf1(DetermineLength1());
// Fill buf1
std::vector<char> buf2(DetermineLength2());
// Fill buf2
return { std::move(buf1), std::move(buf2) };
}
std::pair
LoadData()
{
std::vector buf1(determinateLength1());
//填充buf1
std::向量buf2(determinateLength 2());
//填充buf2
返回{std::move(buf1),std::move(buf2)};
}
如果您仍然需要
int
返回结果,则可以将函数更改为返回std::tuple
。或者更好的方法是,为成员创建一个具有有意义的名称的结构。有什么原因不能对buf1
和buf2
使用std::vector
?通过引用传递到LoadData
,然后可以相应地调用resize
。为什么说“如果不需要,就不要对数组使用std::unique_ptr?”?有没有理由不在这里使用unique_ptr?@Nabi:数组的大小是数组的固有属性。使用唯一的_ptr需要单独存储大小。这很容易出错。本杰明·林德利:是的,你说得对,但是使用向量存储字符数组缓冲区需要更多的内存,而且它的可访问性比char*或unique\ptr或std::string更快。我确信char数组缓冲区的最佳解决方案是使用std::string及其data()函数,但我不喜欢它的名称(string),因为它的数据是一些二进制字节。@Nabi我不太确定vector会变慢。请参见:>性能差异可能是可忽略的或没有(编译器可能会优化它们以使其相同)@不,这个链接与这个比较无关。在某些情况下,字符数组的使用速度非常快,比如批量复制。
std::pair<std::vector<char>, std::vector<char>>
LoadData()
{
std::vector<char> buf1(DetermineLength1());
// Fill buf1
std::vector<char> buf2(DetermineLength2());
// Fill buf2
return { std::move(buf1), std::move(buf2) };
}