gpt4 book ai didi

c++ - std::shared_ptr:未调用自定义删除器

转载 作者:太空狗 更新时间:2023-10-29 19:48:32 26 4
gpt4 key购买 nike

我正在研究 C++ Primer,第 5 版,作者提供了一个示例,使用 shared_ptr 来管理可能泄漏内存的旧库中的资源,以防止它们这样做所以。我决定创建一个测试来查看它是如何工作的,但是我的自定义删除器在异常被抛出并且(故意)没有被捕获后没有被调用:

#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;
}

它产生以下输出:

Connecting to www.google.co.uk

我的理解是函数退出时,无论是正常退出还是异常退出,局部变量都会被销毁。在这种情况下,这应该意味着 connectionAttemptLeaks() 退出时被销毁,调用它的析构函数,然后它应该调用 EndConnection()。另请注意,我正在使用并刷新 cerr,但这也没有提供任何输出。

是我的例子有问题,还是我的理解有问题?

编辑:虽然我已经有了这个问题的答案,但对于将来偶然发现这个问题的其他人来说,我的问题在于我对 throw 工作原理的理解.尽管下面的答案正确地说明了如何使用它,但我认为最好明确说明我正在(错误地)尝试使用它来“生成”未处理的异常,以测试我上面的代码。

最佳答案

Bare throw 用于在 catch block 内重新抛出捕获的异常。如果您在 catch block 之外使用它,terminate() 将被调用并且您的程序立即结束。参见 what does "throw;" outside a catch block do?

如果删除 throw 语句,shared_ptr connection 将超出范围并应调用删除器。如果您对使用 shared_ptr 的异常安全性有任何疑问(我没有;),您可以通过将 throw 更改为 throw 1 来在此处显式抛出异常。

关于c++ - std::shared_ptr:未调用自定义删除器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22331651/

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