C++ 中的容器与智能指针
Containers vs Smart pointers in C++
在 std::containers(std::vector
或 std::array
)和指向数组的智能指针
之间进行选择时如何决定
我知道容器是用于内存管理的对象。它们是异常安全的,不会有任何内存泄漏,它们还提供内存管理功能的真实性(push.back 等),智能指针是也不会泄漏内存的指针,因为它们在不需要时会删除它们不再(如 unique_ptr 超出范围时)。可能在容器中每次创建时都会有开销。
我的问题是如何决定使用哪种方法以及为什么。
std::vector <unsigned char>myArray(3 * outputImageHight * outputImageWidth);
std::unique_ptr<unsigned char[]>myArray(new unsigned char[3 * outputImageHight * outputImageWidth]);
我会使用向量。您的指针版本基本上没有对 vector 进行任何改进,并且您失去了很多有用的功能。您很可能需要测量大小并在某个时候迭代您的数组,您可以免费获得一个向量,而您需要自己为您的指针版本实现它;在这一点上你也可能刚开始使用向量。
可能 实例化向量会产生性能成本,但我怀疑这对大多数应用程序来说是否会成为瓶颈。如果您创建了如此多的向量以致于实例化它们会浪费您的时间,那么您可能会更聪明地管理它们(池化您的内存、自定义向量分配器等)。如有疑问,请测量。
您可能需要使用 unique_ptr<>
版本的一个示例是,如果您正在使用用 C 编写的库,您会失去数组的所有权。例如:
std::unique_ptr<unsigned char[]>myArray(
new unsigned char[3 * outputImageHight * outputImageWidth]);
my_c_lib_data_t cLibData;
int result = my_c_lib_set_image(cLibData, myArray);
if (MYLIB_SUCCESS == result)
// mylib successfully took ownership of the char array, so release the pointer.
myArray.release();
如果您有选择,请尽可能使用 C++ 风格的容器。
始终使用 STL 容器,除非您有充分理由使用指针。原因是可靠性和可读性,IMO。
std::vector
,主要是因为它更好地表示 "sequence of items in contiguous memory",它是 "sequence of items in contiguous memory" 的默认表示,并支持广泛的常见操作。
vector
有移动语义,所以 std::unique_ptr 的好处是有限的。
如果幸运的话,您的 STL 实现`提供小向量优化,跳过小尺寸的内存分配。
-- 编辑:我不知道标准显然禁止 SBO - 抱歉让你抱有希望,谢谢@KarlNicholl
如果需要指针语义,unique_ptr<vector<T>>
或 shared_ptr<vector<T>>
是有效的选择,开销很小。
boost 确实引入了 shared_array
等,它们更好地代表了您的第二个选择,
但我还没有看到他们获得太多关注。
在 std::containers(std::vector
或 std::array
)和指向数组的智能指针
我知道容器是用于内存管理的对象。它们是异常安全的,不会有任何内存泄漏,它们还提供内存管理功能的真实性(push.back 等),智能指针是也不会泄漏内存的指针,因为它们在不需要时会删除它们不再(如 unique_ptr 超出范围时)。可能在容器中每次创建时都会有开销。
我的问题是如何决定使用哪种方法以及为什么。
std::vector <unsigned char>myArray(3 * outputImageHight * outputImageWidth);
std::unique_ptr<unsigned char[]>myArray(new unsigned char[3 * outputImageHight * outputImageWidth]);
我会使用向量。您的指针版本基本上没有对 vector 进行任何改进,并且您失去了很多有用的功能。您很可能需要测量大小并在某个时候迭代您的数组,您可以免费获得一个向量,而您需要自己为您的指针版本实现它;在这一点上你也可能刚开始使用向量。
可能 实例化向量会产生性能成本,但我怀疑这对大多数应用程序来说是否会成为瓶颈。如果您创建了如此多的向量以致于实例化它们会浪费您的时间,那么您可能会更聪明地管理它们(池化您的内存、自定义向量分配器等)。如有疑问,请测量。
您可能需要使用 unique_ptr<>
版本的一个示例是,如果您正在使用用 C 编写的库,您会失去数组的所有权。例如:
std::unique_ptr<unsigned char[]>myArray(
new unsigned char[3 * outputImageHight * outputImageWidth]);
my_c_lib_data_t cLibData;
int result = my_c_lib_set_image(cLibData, myArray);
if (MYLIB_SUCCESS == result)
// mylib successfully took ownership of the char array, so release the pointer.
myArray.release();
如果您有选择,请尽可能使用 C++ 风格的容器。
始终使用 STL 容器,除非您有充分理由使用指针。原因是可靠性和可读性,IMO。
std::vector
,主要是因为它更好地表示 "sequence of items in contiguous memory",它是 "sequence of items in contiguous memory" 的默认表示,并支持广泛的常见操作。
vector
有移动语义,所以 std::unique_ptr 的好处是有限的。
如果幸运的话,您的 STL 实现`提供小向量优化,跳过小尺寸的内存分配。
-- 编辑:我不知道标准显然禁止 SBO - 抱歉让你抱有希望,谢谢@KarlNicholl
如果需要指针语义,unique_ptr<vector<T>>
或 shared_ptr<vector<T>>
是有效的选择,开销很小。
boost 确实引入了 shared_array
等,它们更好地代表了您的第二个选择,
但我还没有看到他们获得太多关注。