gpt4 book ai didi

c++ - 智能指针是否排除了两阶段 build 的需要?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:19:53 25 4
gpt4 key购买 nike

两阶段 build 采用以下形式:

struct something {
something ()
: p1(NULL)
, p2(NULL)
{ }

~something () {
if (p1) delete p1;
if (p2) delete p2;
}

void initialize () {
p1 = new int(2);
p2 = new int(5); // May throw if allocation fails!
}

int* p1;
int* p2;
};

要点在于,天真的构造函数(不监视分配失败)会泄漏内存:永远不会调用部分构造的对象的析构函数。

我的问题:下面的代码是否安全,并且由此推论,智能指针是否避免了两阶段构造?

struct something {
something ()
: p1(new int(2))
, p2(new int(5))
{ }

std::unique_ptr<int> p1;
std::unique_ptr<int> p2;
};

最佳答案

是的,您的新代码没问题。但是请注意,在更复杂的情况下可能会出现微妙的情况:

#include <memory>

struct foo {
foo(std::shared_ptr<int> a, std::shared_ptr<int> b) { }
};

struct bar {
foo f;
bar() : f(std::shared_ptr<int>(new int), std::shared_ptr<int>(new int)) { }
};

int main() {
bar b;
}
但是

并不安全,因为 bar 的初始化列表中 foo 的构造函数参数的求值顺序未指定。符合标准的编译器可能会选择进行深度或广度优先评估(或其他任何事情,只要它们最终都得到正确评估)。这意味着如果第一个 new int 成功,但第二个在 shared_ptr 对象构建之前抛出,第一个要执行的分配仍然可能泄漏。

如果您发现自己想要这样做,除了回到两阶段构造之外,还有两种可能的解决方案:第一种可能是重构,第二种是构造 shared_ptrf 之前,首先单独作为 bar 的成员。哪一个最合适是我认为需要根据具体情况做出的判断。

关于c++ - 智能指针是否排除了两阶段 build 的需要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8064986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com