19

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

vector使用而不是有显着的性能损失unique_ptr吗?

4

5 回答 5

11

std::vector使用vs.没有性能损失std::unique_ptr<int[]>。但是,替代方案并不完全等效,因为向量可以增长而指针不能(这可能是优点或缺点,向量是否错误地增长?)

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

归根结底,我个人会选择 . std::vector<>,但我仍然使用 C++03 编写代码,而没有std::unique_ptr.

于 2013-08-27T18:18:16.290 回答
10

如果你处于一个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默认的构造函数std::string不是强制的。然而:

  1. 这一点可以推广到不涉及的情况std::string
  2. 抛出的std::string默认构造函数是la脚的。
于 2013-08-29T00:33:33.967 回答
5

std::vector存储变量大小和分配数据大小的长度以及指向它自身数据的指针。std::unique_ptr只存储指针,因此使用std::unique_ptr.

还没有人提到 vector 提供了迭代器和函数,而size()unique ptr 没有。因此,如果需要迭代器,请使用std::vector

于 2013-08-27T19:33:33.690 回答
4

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

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

  1. auto buffer = std::make_unique<int[]>( someCount );
  2. auto buffer = std::vector<int>( someCount, someValue );

第一个给你一个未初始化的 int 数组,但第二个用一个值初始化它(如果不提供,则为 0 )。因此,如果您不需要初始化内存,因为您稍后会用比 更复杂的东西覆盖它std::fill,请选择 1,如果没有,请选择 2。

于 2013-08-27T17:29:52.513 回答
1

目标部分:

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

主观部分:

std::vector将为您提供一个众所周知的与和迭代器的接口.size().at()它可以很好地与各种其他代码一起使用。Usingstd::unique_ptr为您提供了一个更原始的界面,并使您可以单独跟踪细节(如大小)。因此,除非有其他限制,我更喜欢std::vector.

于 2013-08-27T19:44:05.397 回答