什么是CInternetSession的必要清理

时间:2015-04-17 15:37:59

标签: c++ mfc

CInternetSession::Close()的MSDN文档只说

  

当您的应用程序使用CInternetSession对象时,请调用此成员函数。

     

MSDN for CInternetSession::Close

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

我在MSDN上找不到CHttpConnection::Close()的文档,CHttpFileClose()继承了CInternetFile方法;其文档同样无益:

  

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

     

(抱歉,我不能有三个链接)

我的直觉假设是CInternetSession::GetHttpConnection()CHttpConnection::OpenRequest()返回指针,因为CHttpConnection的MSDN说

  

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

     

(抱歉,我不能有三个链接)

CInternetSession内部存储对其生成的CHttpConnection的引用,并在调用CInternetSession::Close()时清除该对象。这由this MSDN article支持,它没有提到连接对象的任何清理,并且声明了

  

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

简短的问题

这是必要的吗?

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

... Do stuff ...

file->Close();
delete file;

connection->Close();
delete connection;

session.Close();

或者足以做到:

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

... Do stuff ...

session.Close();

元问题

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

1 个答案:

答案 0 :(得分:2)

简短的回答是你不必调用Close(),它由MFC析构函数完成。理想情况下,析构函数应该进行所有必要的清理。

如您所述,MFC类的记录很少。 WinINet函数有更好的文档:

MSDN WinINet functions

例如,它必须使用::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();
}

因此我们不需要调用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

简短版本:

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

顺便说一下,将断点放在CInternetSession obj上并踩到它,还应该带你到MFC文件..\VC\atlmfc\src\mfc\inet.cpp