Std::unique_ptr支持数组,例如:
std::unique_ptr<int[]> p(new int[10]);
但这是必要的吗?可能使用std::vector或std::array更方便。
你觉得这个结构有什么用处吗?
Std::unique_ptr支持数组,例如:
std::unique_ptr<int[]> p(new int[10]);
但这是必要的吗?可能使用std::vector或std::array更方便。
你觉得这个结构有什么用处吗?
当前回答
I have used unique_ptr<char[]> to implement a preallocated memory pools used in a game engine. The idea is to provide preallocated memory pools used instead of dynamic allocations for returning collision requests results and other stuff like particle physics without having to allocate / free memory at each frame. It's pretty convenient for this kind of scenarios where you need memory pools to allocate objects with limited life time (typically one, 2 or 3 frames) that do not require destruction logic (only memory deallocation).
其他回答
unique_ptr<char[]>可以用在你想要C的性能和c++的便利性的地方。假设您需要操作数百万(好吧,如果您还不相信,则需要操作数十亿)字符串。将它们分别存储在单独的string或vector<char>对象中对于内存(堆)管理例程来说是一场灾难。特别是当您需要多次分配和删除不同的字符串时。
但是,您可以为存储这么多字符串分配一个缓冲区。你不会喜欢char* buffer = (char*)malloc(total_size);出于显而易见的原因(如果不明显,搜索“为什么使用智能ptrs”)。unique_ptr<char[]> buffer(new char[total_size]);
通过类比,同样的性能和便利性考虑也适用于非字符数据(考虑数百万个向量/矩阵/对象)。
I have used unique_ptr<char[]> to implement a preallocated memory pools used in a game engine. The idea is to provide preallocated memory pools used instead of dynamic allocations for returning collision requests results and other stuff like particle physics without having to allocate / free memory at each frame. It's pretty convenient for this kind of scenarios where you need memory pools to allocate objects with limited life time (typically one, 2 or 3 frames) that do not require destruction logic (only memory deallocation).
在一些Windows Win32 API调用中可以找到一个常见的模式,其中使用std::unique_ptr<T[]>可以派上用场,例如,当你调用一些Win32 API(将在该缓冲区中写入一些数据)时,不知道输出缓冲区应该有多大:
// Buffer dynamically allocated by the caller, and filled by some Win32 API function.
// (Allocation will be made inside the 'while' loop below.)
std::unique_ptr<BYTE[]> buffer;
// Buffer length, in bytes.
// Initialize with some initial length that you expect to succeed at the first API call.
UINT32 bufferLength = /* ... */;
LONG returnCode = ERROR_INSUFFICIENT_BUFFER;
while (returnCode == ERROR_INSUFFICIENT_BUFFER)
{
// Allocate buffer of specified length
buffer.reset( BYTE[bufferLength] );
//
// Or, in C++14, could use make_unique() instead, e.g.
//
// buffer = std::make_unique<BYTE[]>(bufferLength);
//
//
// Call some Win32 API.
//
// If the size of the buffer (stored in 'bufferLength') is not big enough,
// the API will return ERROR_INSUFFICIENT_BUFFER, and the required size
// in the [in, out] parameter 'bufferLength'.
// In that case, there will be another try in the next loop iteration
// (with the allocation of a bigger buffer).
//
// Else, we'll exit the while loop body, and there will be either a failure
// different from ERROR_INSUFFICIENT_BUFFER, or the call will be successful
// and the required information will be available in the buffer.
//
returnCode = ::SomeApiCall(inParam1, inParam2, inParam3,
&bufferLength, // size of output buffer
buffer.get(), // output buffer pointer
&outParam1, &outParam2);
}
if (Failed(returnCode))
{
// Handle failure, or throw exception, etc.
...
}
// All right!
// Do some processing with the returned information...
...
当你只能通过一个现有的API(窗口消息或线程相关的回调参数)插入一个指针时,它们可能是正确的答案,这些指针在被“捕捉”到另一边后具有一定的生命周期,但与调用代码无关:
unique_ptr<byte[]> data = get_some_data();
threadpool->post_work([](void* param) { do_a_thing(unique_ptr<byte[]>((byte*)param)); },
data.release());
我们都希望事情对自己有利。c++是其他时候用的。
您可能使用unique_ptr的一个原因是,如果您不想支付初始化数组值的运行时成本。
std::vector<char> vec(1000000); // allocates AND value-initializes 1000000 chars
std::unique_ptr<char[]> p(new char[1000000]); // allocates storage for 1000000 chars
// C++20 version:
auto p = std::make_unique_for_overwrite<char[]>(1000000);
std::vector构造函数和std::vector::resize()将对t进行值初始化,但new和std::make_unique_for_overwrite将默认初始化它们,这对于PODs来说意味着什么都不做。
参见c++ 11中的值初始化对象和std::vector构造函数
注意,vector::reserve在这里不是一个替代方案:在std::vector::reserve之后访问原始指针是安全的吗?
这和C程序员选择malloc而不是calloc的原因是一样的。