如果您不需要动态增长并且在编译时不知道缓冲区的大小,那么应该何时unique_ptr<int[]>
使用而不是使用vector<int>
if 呢?
vector
使用而不是有显着的性能损失unique_ptr
吗?
如果您不需要动态增长并且在编译时不知道缓冲区的大小,那么应该何时unique_ptr<int[]>
使用而不是使用vector<int>
if 呢?
vector
使用而不是有显着的性能损失unique_ptr
吗?
std::vector
使用vs.没有性能损失std::unique_ptr<int[]>
。但是,替代方案并不完全等效,因为向量可以增长而指针不能(这可能是优点或缺点,向量是否错误地增长?)
还有其他差异,例如值将在 中初始化,但如果您使用数组std::vector
则不会(除非您使用值初始化......)。new
归根结底,我个人会选择 . std::vector<>
,但我仍然使用 C++03 编写代码,而没有std::unique_ptr
.
如果你处于一个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
不是强制的。然而:
std::string
。std::string
默认构造函数是la脚的。std::vector
存储变量大小和分配数据大小的长度以及指向它自身数据的指针。std::unique_ptr
只存储指针,因此使用std::unique_ptr
.
还没有人提到 vector 提供了迭代器和函数,而size()
unique ptr 没有。因此,如果需要迭代器,请使用std::vector
C++14 为此目的引入了 std::dynarray。
现在,在这两种结构之间:
auto buffer = std::make_unique<int[]>( someCount );
auto buffer = std::vector<int>( someCount, someValue );
第一个给你一个未初始化的 int 数组,但第二个用一个值初始化它(如果不提供,则为 0 )。因此,如果您不需要初始化内存,因为您稍后会用比 更复杂的东西覆盖它std::fill
,请选择 1,如果没有,请选择 2。
目标部分:
不,两者之间可能不应该有显着的性能差异(尽管我认为这取决于实现,您应该衡量它是否至关重要)。
主观部分:
std::vector
将为您提供一个众所周知的与和迭代器的接口.size()
,.at()
它可以很好地与各种其他代码一起使用。Usingstd::unique_ptr
为您提供了一个更原始的界面,并使您可以单独跟踪细节(如大小)。因此,除非有其他限制,我更喜欢std::vector
.