使用什么std :: optional或std :: unique_ptr

时间:2017-07-01 01:54:40

标签: c++ optional unique-ptr

我有一个动态分配成员的类(仅在使用时才分配)。

想想这样的事情:

class A {};

class B {
    A* aMember;
};

最好替换A*std::optionalstd::unique_ptr

以及何时使用std::optional代替std::unique_ptr

1 个答案:

答案 0 :(得分:11)

std::optional<A>保证不会发生辅助内存分配。这意味着A类型的潜在对象的原始缓冲区嵌入到std::optional<A>中。它是std::optional内存占用的一个组成部分。这意味着std::optional<A>的内存大小总是至少为sizeof(A),无论该可选A对象当前是否存在。这就是std::optional<A>B总大小的贡献。

std::unique_ptr<A>是一个指针。它的大小与常规裸指针的大小大致相同。这就是std::unique_ptr<A>内部B占用的内存量。{1}}。为了使其指向有效的A对象,您必须独立地在其他地方分配A。当A存在时,它会占用内存。当A不存在时,它不会占用内存。

在做出决定时,需要考虑以上因素。 std::optional<A>不涉及动态内存分配/释放,但您为此付出的代价可能是“{1}}内部浪费”的内存。使用std::optional<A>进行大规模实例化和/或大型对象可能会非常浪费,特别是如果对象的大部分生命周期都处于空状态。

这意味着std::optional的目的并非完全针对可选的长期存储。 std::optional本地使用的内容:例如:作为可选的本地值,函数的可选参数,可选的返回值。只要您没有大量实例化此类对象,长期使用也是可以的。

std::optional不会浪费内存,但您为此付出的代价是动态内存分配/释放。

当然,所有权语义也大不相同。 std::unique_ptr<A>是可复制的。 std::optional是可移动的,但不可复制。