Std::unique_ptr支持数组,例如:

std::unique_ptr<int[]> p(new int[10]);

但这是必要的吗?可能使用std::vector或std::array更方便。

你觉得这个结构有什么用处吗?


当前回答

如果您需要一个不可复制构造的对象的动态数组,那么可以使用一个指向数组的智能指针。例如,如果您需要一个原子数组怎么办?

其他回答

unique_ptr<char[]>可以用在你想要C的性能和c++的便利性的地方。假设您需要操作数百万(好吧,如果您还不相信,则需要操作数十亿)字符串。将它们分别存储在单独的string或vector<char>对象中对于内存(堆)管理例程来说是一场灾难。特别是当您需要多次分配和删除不同的字符串时。

但是,您可以为存储这么多字符串分配一个缓冲区。你不会喜欢char* buffer = (char*)malloc(total_size);出于显而易见的原因(如果不明显,搜索“为什么使用智能ptrs”)。unique_ptr<char[]> buffer(new char[total_size]);

通过类比,同样的性能和便利性考虑也适用于非字符数据(考虑数百万个向量/矩阵/对象)。

我对公认答案的精神再怎么反对也不为过。“最后的手段”?远非如此!

在我看来,与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.

出于二进制兼容性的考虑,您需要结构只包含一个指针。 你需要使用一个API来返回用new[]分配的内存 例如,您的公司或项目有一个禁止使用std::vector的一般规则,以防止粗心的程序员不小心引入副本 您希望防止粗心的程序员在这种情况下意外地引入副本。

有一个普遍的规则,c++容器比使用指针滚动自己的容器更受欢迎。这是一个普遍规律;它有例外。有更多的;这些只是例子。

Scott Meyers在《Effective Modern c++》中这样说

对于数组来说,是否存在std::unique_ptr应该只对你的智力感兴趣,因为std::array, Std::vector, Std::string实际上总是比原始数组更好的数据结构选择。关于我能想到的唯一情况,当std::unique_ptr<T[]>有意义时,当你使用一个类似c的API,返回一个原始指针指向你假定拥有的堆数组时。

我认为Charles Salvia的答案是相关的:std::unique_ptr<T[]>是初始化一个在编译时不知道大小的空数组的唯一方法。对于使用std::unique_ptr<T[]>的动机,Scott Meyers会说些什么呢?

与std::vector和std::array相反,std::unique_ptr可以拥有一个NULL指针。 这在使用期望数组或NULL的C api时非常方便:

void legacy_func(const int *array_or_null);

void some_func() {    
    std::unique_ptr<int[]> ptr;
    if (some_condition) {
        ptr.reset(new int[10]);
    }

    legacy_func(ptr.get());
}