什么是CInternetSession的必要清理

Dav*_*zyk 5 c++ mfc

MSDN文档CInternetSession::Close()仅用于说明

在应用程序使用完CInternetSession对象后调用此成员函数.

CInternetSession的MSDN ::关闭

对于CHttpConnection返回的对象CInternetSession::GetHttpConnection()CHttpFile返回的CHttpConnection::OpenRequest()对象,是否必须手动关闭和删除这些对象?

CHttpConnection::Close()在MSDN上找不到文档,并从中CHttpFile继承了它的Close()方法CInternetFile; 其文档同样无益:

关闭CInternetFile并释放其任何资源.

(对不起,我不能有三个链接)

我的直觉假设是自从CInternetSession::GetHttpConnection()CHttpConnection::OpenRequest()返回指针,并且自从MSDN CHttpConnection表示

你永远不会CHttpConnection直接创建一个对象; 相反,调用CInternetSession::GetHttpConnection,创建CHttpConnection对象并返回指向它的指针.

(对不起,我不能有三个链接)

CInternetSession内部存储CHttpConnection对其生成的引用,并在CInternetSession::Close()调用时清理该对象.这篇MSDN文章支持这一点,该文章未提及连接对象的任何清理和状态

处理CInternetSession对象 - >自动清理打开的文件句柄和连接.

简短的问题

这是必要的:

CInternetSession session(...);
CHttpConnection * connection = session.GetHttpConnection(...);
CHttpFile * file = connection->OpenRequest(...);

... Do stuff ...

file->Close();
delete file;

connection->Close();
delete connection;

session.Close();
Run Code Online (Sandbox Code Playgroud)

或者它足以做到:

CInternetSession session(...);
CHttpConnection * connection = session.GetHttpConnection(...);
CHttpFile * file = connection->OpenRequest(...);

... Do stuff ...

session.Close();
Run Code Online (Sandbox Code Playgroud)

元问题

如果---来自图书馆的文档---不清楚清理资源的责任在哪里,有哪些可能的方法来检测资源泄漏?我知道Valgrind可以用于内存泄漏,但是文件句柄和其他可能被绑定的资源呢?

Bar*_*ani 3

简而言之,您不必调用Close(),它由 MFC 析构函数完成。理想情况下,析构函数应该执行所有必要的清理工作。

正如您所指出的,MFC 类的文档记录很差。WinINet 函数有更好的文档:

MSDN WinINet 函数

例如,它表示::InternetOpen句柄必须用 关闭InternetCloseHandle。我们可以看一下MFC类的定义并进行比较:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\src\mfc\inet.cpp

CInternetSession(){
    ::InternetOpen //WinINet
    ...
}

CInternetSession::Close(){
    ::InternetCloseHandle //WinINet
    ...
}

CInternetSession::~CInternetSession(){
    Close();
}
Run Code Online (Sandbox Code Playgroud)

所以我们不需要调用,internetSession.Close()因为它是由析构函数自动完成的。不过打电话也没什么坏处。我想如果CInternetSession在堆或其他东西上声明,那么我们可能需要这样做,Close()因为在调用析构函数之前可能需要一些时间。

在另一个例子中,我们不必调用Close任何一个,但这并没有什么坏处。

CHttpFile * file = connection->OpenRequest(...);
file->Close();//I think this is okay but not necessary because we "delete file" in next line
delete file;//calls Close(); and other necessary cleanups
Run Code Online (Sandbox Code Playgroud)

简洁版本:

CInternetSession session(...);
CHttpConnection *connection = session.GetHttpConnection(...);
CHttpFile *file = connection->OpenRequest(...);
//... Do stuff ...
delete file;//don't skip
delete connection;//don't skip
//session.Close();//you can skip, this gets called when we exist the function
Run Code Online (Sandbox Code Playgroud)

顺便说一句,设置断点CInternetSession obj并单步执行,也应该将您带到 MFC 文件..\VC\atlmfc\src\mfc\inet.cpp