std::shared_ptr:未调用自定义删除器
std::shared_ptr: Custom deleter not being invoked
我正在阅读c++ Primer,第5版,作者提供了一个使用shared_ptr
s来管理可能泄漏内存的旧库资源的示例,以防止它们这样做。我决定创建一个测试来看看它是如何工作的,但是我的自定义删除器在抛出异常之后不会被调用,并且(故意)没有被捕获:
#include <iostream>
#include <memory>
#include <string>
struct Connection {};
Connection* Connect(std::string host)
{
std::cout << "Connecting to " << host << std::endl;
return new Connection;
}
void Disconnect(Connection* connection)
{
std::cout << "Disconnected" << std::endl;
delete connection;
}
void EndConnection(Connection* connection)
{
std::cerr << "Calling disconnect." << std::endl << std::flush;
Disconnect(connection);
}
void AttemptLeak()
{
Connection* c = Connect("www.google.co.uk");
std::shared_ptr<Connection> connection(c, EndConnection);
// Intentionally let the exception bubble up.
throw;
}
int main()
{
AttemptLeak();
return 0;
}
输出如下:
连接到www.google.co.uk
我的理解是,当一个函数退出时,无论是正常退出还是因为异常退出,局部变量都将被销毁。在这种情况下,这应该意味着connection
在AttemptLeaks()
退出时被销毁,调用其析构函数,然后调用EndConnection()
。还请注意,我正在使用并刷新cerr
,但这也没有给出任何输出。
是我的例子有问题,还是我的理解有问题?
编辑:虽然我已经有了这个问题的答案,但对于将来偶然发现这个问题的任何人,我的问题是我对throw
如何工作的理解。虽然下面的答案正确地说明了如何使用它,但我认为最好明确地说明一下,我(错误地)试图使用它来"生成"一个未处理的异常,以测试上面的代码。
裸throw
用于在catch块内重新抛出捕获的异常。如果你在catch块外使用它,terminate()
将被调用,你的程序立即结束。看看"扔"了什么;外面一个接球块怎么办?
如果您删除throw
-语句,shared_ptr
connection
将超出作用域,并且应该调用delete。如果您对使用shared_ptr的异常安全性有任何疑问(我没有;),您可以通过将throw
更改为throw 1
来显式抛出异常。
没有操作数的throw
表达式用于重新抛出当前正在处理的异常。如果没有处理异常,则调用std::terminate
。在这种情况下,不会进行堆栈展开,这就是为什么永远不会调用删除程序的原因。将代码更改为以下内容:
void AttemptLeak()
{
Connection* c = Connect("www.google.co.uk");
std::shared_ptr<Connection> connection(c, EndConnection);
// Intentionally let the exception bubble up.
throw 42; // or preferably something defined in <stdexcept>
}
int main()
{
try {
AttemptLeak();
} catch(...) {
}
return 0;
}
现在,当shared_ptr
超出作用域时,将调用删除器
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 如何使用 C 指针的自定义删除器创建unique_ptr?
- 在地图中使用自定义删除器存储unique_ptr
- 指向重载静态成员的函数指针 - 在unique_ptr中用作自定义删除器
- 在unique_ptr<>中使用自定义删除程序 (curl_formfree())
- C++自定义删除运算符不能正常工作?
- 如何在我的类unique_ptr中提供自定义删除器?
- 无法使用带有 std::move 的自定义删除器插入 std::unique_ptr
- 未调用 std::unique_ptr 中的自定义删除器
- 如何为unique_ptr管理的数组编写自定义删除器?
- 适用于 std::unique_ptr 的内存高效自定义删除器?
- 用于unique_ptr的有状态自定义删除程序
- shared_ptr<>到数组自定义删除器(带make_shared)
- 为什么使用自定义删除器unique_ptr不适用于 nullptr,而shared_ptr则适用于 nullptr?
- 如何在自定义删除器的情况下复制unique_ptr
- 自定义删除器,用于shared_ptr<>给出"无上下文错误"
- 智能指针自定义删除器中的处理条件
- 为什么unique_ptr不能阻止自定义删除程序的切片?
- 提升共享指针自定义删除器示例
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?