2017-05-09 35 views
0

下面的函数可以工作,但在我看来它有非常难闻的气味。C++很少使用istream指针和refferecnes和重构

我的项目通过HTTP与设备进行通信,它有一些带有摘要式身份验证的URL,有些页面没有。 一些网址压缩与deflate,一些没有。所以我的功能有3种不同的方式来获取istream。 我需要在函数底部的一个地方读取istream。 但是,从另一个我的问题C++ variable visable scopes and strems说好人,在这种情况下指针是不好的。

而在这段代码中有时会创建动态对象。

Poco::InflatingInputStream* inflater = new Poco::InflatingInputStream(*respStreamPtr); 

这是内存泄漏的途径吗?

如果没有语句来创建吹气,然后* respStreamPtr没有数据出来,如果块范围。

所以,请给我建议如何以正确的方式重构此代码。

std::ostream& requestStream = session->sendRequest(request); 
    istream* respStreamPtr; 
    respStreamPtr = &session->receiveResponse(response); 
    if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) 
    { 
     credentials->authenticate(request, response); 
     session->sendRequest(request); 
     respStreamPtr = &session->receiveResponse(response); 
    } 
    if (response.has("Content-Encoding") && response.get("Content-Encoding") == "deflate") { 
     Poco::InflatingInputStream* inflater = new Poco::InflatingInputStream(*respStreamPtr); 
     respStreamPtr = &std::istream(inflater->rdbuf()); 
    } 
    std::ostringstream stringStream; 
    stringStream << respStreamPtr->rdbuf(); 
    responseBody = stringStream.str(); 

回答

0

是的,这将是一个内存泄漏,因为每次使用new它会创建一个新的对象,你永远不delete

但是,你使用它的声明范围内的inflater变量外因此目前无法在不修改其他代码的情况下很好地删除它。对于一个简单的修复,您可以在代码的顶部声明Poco::InflatingInputStream* inflater = nullptr;,然后在最后删除它。

我强烈建议你阅读了关于如何在C正确地管理内存++,甚至考虑看看智能指针(但并非没有学习第一基本面)

波科实际上有功能,它做了很多你想要做什么,所以你的例子可以很容易凝结(免责声明:未经测试):

session->sendRequest(request); 
auto& responseStream = session->receiveResponse(response); 
if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) 
{ 
    credentials->authenticate(request, response); 
    session->sendRequest(request); 
    responseStream = session->receiveResponse(response); 
} 
if (response.has("Content-Encoding") && response.get("Content-Encoding") == "deflate") 
{ 
    Poco::InflatingInputStream inflater(responseStream); 
    StreamCopier::copyStream(inflater, responseStream); 
} 
responseBody << responseStream; 
+0

建议改变'波科:: InflatingInputStream *吹气;''来::波科* InflatingInputStream吹气= nullptr;'所以你知道,如果未使用,最后删除将是安全的。 – user4581301

+1

是的,谢谢!假设在删除之前添加了对nullptr的检查 –

+0

Jnny Paton的代码不起作用。在第一个错误代替第二个任务:'responseStream = session-> receiveResponse(response);'With massage **“无法引用”**。而且我可以理解这是正确的,因为responseStream是参考。 StreamCopier :: copyStream(inflater,responseStream)中的第二个错误;' 带有消息:**不能用类型“std :: istream”的值初始化** – greenif