std::unique_ptr 取消引用异常未在 try-catch 块中捕获
Posted
技术标签:
【中文标题】std::unique_ptr 取消引用异常未在 try-catch 块中捕获【英文标题】:std::unique_ptr dereference exception not catch-ed in try-catch block 【发布时间】:2018-05-22 09:49:50 【问题描述】:假设我有:
struct test
bool a;
int b;
;
int main()
std::unique_ptr<test> ptr;
// don't init the ptr
try
if (!ptr->a)
std::cout << "ok" << std::endl;
catch (const std::exception &ex)
std::cout << "ex: " << ex.what() << std::endl;
return 1;
所以在这里我设置了一个唯一指针,但我没有初始化它(在更大的代码库中模拟它)但我想捕获异常。
问题是我的异常没有被调用——我只是崩溃了(内存访问错误)
我阅读了一些类似的问题(但不完全相同),这些问题表明我通过引用传递了异常 - 但这不起作用。
那么是否有可能捕获 unique_ptr 取消引用异常?
编辑:我应该补充一点,这是在运行 MSVS2012 可执行文件的 Windows 7 机器上 - 如果它是相关的!
【问题讨论】:
取消引用未初始化的指针是未定义的行为,不会引发异常。 @RichardCritten 哦....有没有办法做我想做的事? - 我有一个 unique_ptr 的列表 - 我试图通过在它周围放置一个 try 块来避免单独检查每个...但是如果它没有引发异常,那么我想我必须在每个周围做if (ptr) ...
?
为什么你拥有不拥有任何东西的智能指针 (std::unique_ptr
)?这感觉像是一个 XY 问题。
@RichardCritten 我正在使用智能指针,这样我就不必担心垃圾收集等等......在我的代码中,当我创建一个新指针时,构造函数(类型为指向 ) 可能会失败,如果是这样,智能指针实际上是 nullptr。所以我想测试一下这个条件......
当正在构造的对象失败并且不创建std::unique_ptr`时抛出异常。
【参考方案1】:
那么是否有可能捕获 unique_ptr 取消引用异常?
没有要捕获的unique_ptr
取消引用异常。
作为documentation says,
如果
get() == nullptr
,则行为未定义
您可以使用这种类似 Java 的行为轻松编写自己的智能指针,但这确实意味着在 每个 取消引用时都要为测试和分支付费,这通常看起来很愚蠢。
对于cmets中描述的略有不同的问题:
我有一个 unique_ptr 的列表 - 我试图通过在其周围放置一个 try 块来避免单独检查每个。
理智的解决方案可能是检查一次,而不是每次取消引用:
if(any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>)
throw MyNullPointerException();
对于后续的 cmets,您可以在构造函数中添加一个 check-and-throw 包装器。
在 C++17 中,您几乎可以通过返回 optional<unique_ptr<test>>
(即,它包含填充的 unique_ptr
,或根本不包含任何内容:在这种情况下,调用 value
来提取unique_ptr
会抛出 std::bad_optional_access
如果那里真的没有)。
如果你可以导入 ot(或者没有 C++17),GSL 可能会更好用gsl::not_null<T>
。例如,您可以将这些东西存储在您的容器中
using unique_not_null = std::unique_ptr<gsl::not_null<test>>;
【讨论】:
“你可以在你的构造函数中添加一个检查并抛出包装器” - 比如gsl::not_null
?以上是关于std::unique_ptr 取消引用异常未在 try-catch 块中捕获的主要内容,如果未能解决你的问题,请参考以下文章
对Windows HANDLE使用std :: unique_ptr
std::list< std::unique_ptr<T> >:传递它
C++:通过引用 unique_ptr 对象使 unique_ptr 为空