我正在研究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
工作原理的理解。尽管下面的答案正确说明了如何使用它,但我认为最好明确表明我(错误地)试图使用它来“生成”未处理的异常,以测试我的代码。
Barethrow
旨在用于catch块内部以重新抛出捕获的异常。如果在catch块外使用它,terminate()
将被调用,并且程序立即结束。看看“抛出”是什么 外面有挡水板吗?
如果删除throw
-statement,shared_ptr
connection
将超出范围,应调用删除程序。如果您对使用shared_ptr的异常安全性有任何疑问(我不会;),可以通过将更throw
改为来在此处显式抛出异常throw 1
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句