我偶然发现了这样的代码:
void foo(T* bar); // Note: takes ownership of 'bar'.
foo(new T());现在我想知道是否有必要将其重构为:
void foo(T* bar); // Note: takes ownership of 'bar'.
auto tempT = std::make_unique<T>();
foo(tempT.release());虽然从参数列表中调用“新”一词已经非常清楚地表明了这一点,但exception-safe?
请注意,不幸的是,我不能更改'foo‘的签名。
发布于 2021-09-10 18:06:03
,它是否更加异常安全?
不是的。然而,考虑一个稍微复杂的例子:
auto tempT = std::make_unique<T>();
some_operation();
foo(tempT.release());在这种情况下,如果不使用unique_ptr,就会出现异常安全的潜在问题。
尽管如此,安全得多的是:
void foo(std::unique_ptr<T> bar); // no need to note that takes ownership
// because that's implied by the type注意,不幸的是,我不能更改'foo‘的签名。
然后编写一个您可以控制的包装函数。
发布于 2021-09-10 18:04:38
不,也不例外。
但是,请考虑函数是否更改为接受更多的参数:
void foo(T* bar, T* more_bar = get_more_bar()); // Note: takes ownership of both.
foo(new T());现在,如果get_more_bar()在new T()之后进行评估并抛出怎么办。
发布于 2021-09-10 18:12:01
您可以考虑为foo编写一个包装器:
void wrap_foo(std::unique_ptr<T> arg) {
foo(arg.get());
arg.release();
}如果foo在不释放内存的情况下抛出异常,这将释放它。但是,如果foo已经是异常安全的,并且在抛出异常之前释放内存,这将释放它两次。不巧的是,没有一种很好的方法来编写一个安全的包装器来检测内存是否已被正确释放。
https://stackoverflow.com/questions/69136272
复制相似问题