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).
其他回答
std::vector可以被复制,而unique_ptr<int[]>允许表示数组的唯一所有权。另一方面,Std::array要求在编译时确定大小,这在某些情况下可能是不可能的。
允许和使用std::unique_ptr<T[]>的另一个原因是,到目前为止还没有在响应中提到:它允许向前声明数组元素类型。
当您希望最小化头文件中的链式#include语句(以优化构建性能)时,这非常有用。
例如:
myclass.h:
class ALargeAndComplicatedClassWithLotsOfDependencies;
class MyClass {
...
private:
std::unique_ptr<ALargeAndComplicatedClassWithLotsOfDependencies[]> m_InternalArray;
};
myclass.cpp:
#include "myclass.h"
#include "ALargeAndComplicatedClassWithLotsOfDependencies.h"
// MyClass implementation goes here
使用上面的代码结构,任何人都可以#include " MyClass .h"并使用MyClass,而不必包括MyClass::m_InternalArray所要求的内部实现依赖。
如果m_InternalArray被声明为std::array< alargeandcomplatedclasswithlotsofdependencies >,或者std::vector<…> -结果将尝试使用不完整的类型,这是一个编译时错误。
出于二进制兼容性的考虑,您需要结构只包含一个指针。 你需要使用一个API来返回用new[]分配的内存 例如,您的公司或项目有一个禁止使用std::vector的一般规则,以防止粗心的程序员不小心引入副本 您希望防止粗心的程序员在这种情况下意外地引入副本。
有一个普遍的规则,c++容器比使用指针滚动自己的容器更受欢迎。这是一个普遍规律;它有例外。有更多的;这些只是例子。
这里有权衡,您可以选择与您想要的匹配的解决方案。我能想到的是:
初始大小
vector和unique_ptr<T[]>允许在运行时指定大小 数组只允许在编译时指定大小
调整
array和unique_ptr<T[]>不允许调整大小 向量是
存储
vector和unique_ptr<T[]>将数据存储在对象之外(通常在堆上) 数组将数据直接存储在对象中
复制
数组和向量允许复制 unique_ptr<T[]>不允许复制
交换/移动
vector和unique_ptr<T[]>有O(1)次交换和移动操作 数组有O(n)次交换和移动操作,其中n是数组中元素的数量
指针/引用/迭代器失效
array ensures pointers, references and iterators will never be invalidated while the object is live, even on swap() unique_ptr<T[]> has no iterators; pointers and references are only invalidated by swap() while the object is live. (After swapping, pointers point into to the array that you swapped with, so they're still "valid" in that sense.) vector may invalidate pointers, references and iterators on any reallocation (and provides some guarantees that reallocation can only happen on certain operations).
概念和算法的兼容性
array和vector都是容器 unique_ptr<T[]>不是容器
我不得不承认,对于基于策略的设计来说,这似乎是一个重构的机会。
我对公认答案的精神再怎么反对也不为过。“最后的手段”?远非如此!
在我看来,与C语言和其他类似语言相比,c++最强大的特性之一是能够表达约束,以便在编译时检查它们,并防止意外误用。因此,在设计结构时,要问问自己它应该允许哪些操作。应该禁止所有其他用途,最好能够静态地(在编译时)实现这些限制,以免误用导致编译失败。
因此,当需要一个数组时,以下问题的答案指定了它的行为: 1. 它的大小是a)在运行时动态的,还是b)静态的,但只在运行时知道,还是c)静态的,在编译时知道? 2. 数组是否可以分配到堆栈上?
根据这些答案,我认为这是这种数组的最佳数据结构:
Dynamic | Runtime static | Static
Stack std::vector unique_ptr<T[]> std::array
Heap std::vector unique_ptr<T[]> unique_ptr<std::array>
是的,我认为unique_ptr<std::array>也应该被考虑,这两个都不是最后的工具。想想什么最适合你的算法。
所有这些都通过指向数据数组的原始指针(vector.data() / array.data() / uniquePtr.get())与普通C api兼容。
P. S. Apart from the above considerations, there's also one of ownership: std::array and std::vector have value semantics (have native support for copying and passing by value), while unique_ptr<T[]> can only be moved (enforces single ownership). Either can be useful in different scenarios. On the contrary, plain static arrays (int[N]) and plain dynamic arrays (new int[10]) offer neither and thus should be avoided if possible - which should be possible in the vast majority of cases. If that wasn't enough, plain dynamic arrays also offer no way to query their size - extra opportunity for memory corruptions and security holes.