unique_ptr <int []>或vector <int>?</int> </int []>

时间:2013-08-27 17:24:58

标签: c++ vector unique-ptr

如果您不需要动态增长并且在编译时不知道缓冲区的大小,那么何时应该使用unique_ptr<int[]>而不是vector<int>

使用vector代替unique_ptr是否会导致性能下降?

5 个答案:

答案 0 :(得分:7)

如果您处于vector<int>甚至可能的位置,您可能希望在极端和罕见的情况下使用它。即便如此,自定义类型而非unique_ptr<int[]>可能是最佳答案。

那么unique_ptr<int[]>有什么用呢? : - )

unique_ptr<T[]>在两种情况下真的很棒:

1.您需要处理来自某些遗留函数的malloc / free资源,并且您希望以现代异常安全样式执行此操作:

void
foo()
{
    std::unique_ptr<char[], void(*)(void*)> p(strdup("some text"), std::free);
    for (unsigned i = 0; p[i]; ++i)
        std::cout << p[i];
    std::cout << '\n';
}

2.您需要暂时保护新的[]资源,然后再将其转移给其他所有者:

class X
{
    int* data_;
    std::string name_;

    static void validate(const std::string& nm);
public:
    ~X() {delete [] data_;}

    X(int* data, const std::string& name_of_data)
        : data_(nullptr),
          name_()
    {
        std::unique_ptr<int[]> hold(data);  // noexcept
        name_ = name_of_data;               // might throw
        validate(name_);                    // might throw
        data_ = hold.release();             // noexcept
    }
};

在上面的场景中,X拥有传递给它的指针,无论构造函数是否成功。此特定示例假定noexcept的{​​{1}}默认构造函数未被强制执行。但是:

  1. 这一点可以推广到不涉及std::string的情况。
  2. 抛出的std::string默认构造函数是lame。

答案 1 :(得分:5)

使用std::vectorstd::unique_ptr<int[]>时没有性能损失。但是,替代方案并不完全相同,因为矢量可以增长而指针不能(这可能是优势还是劣势,矢量是否会错误增长?)

还有其他差异,例如值将在std::vector中初始化,但如果您new数组,则不会出现这些差异(除非您使用值初始化 ...)。

在一天结束时,我个人会选择std::vector<>,但我仍然使用std::unique_ptr在C ++ 03中编码。

答案 2 :(得分:4)

C ++ 14为此目的引入了std :: dynarray。

现在,在这两个结构之间:

  1. auto buffer = std::make_unique<int[]>( someCount );
  2. auto buffer = std::vector<int>( someCount, someValue );
  3. 第一个给你一个未初始化的int数组,但是第二个用一个值初始化它(如果不提供则为0)。因此,如果您不需要初始化内存,因为稍后会以比std::fill更复杂的内容覆盖它,请选择1,否则请选择2.

答案 3 :(得分:4)

std::vector存储变量大小和分配数据大小的长度以及指向其自身数据的指针。 std::unique_ptr只存储指针,因此使用std::unique_ptr可能会有很小的收获。

还没有人提到过这个向量提供了迭代器和函数,而size()就像唯一的ptr那样。因此,如果需要迭代器,请使用std::vector

答案 4 :(得分:1)

目标部分:

不,两者之间可能不会有显着的性能差异(虽然我认为这取决于实施,你应该衡量它是否至关重要。)

主观部分:

std::vector将为您提供一个与.size().at()以及迭代器的众所周知的接口,它将与各种其他代码很好地配合使用。使用std::unique_ptr为您提供了更原始的界面,使您可以分别跟踪详细信息(如大小)。因此,除了其他限制之外,我更希望std::vector