我有一个简单的问题。我有一个我写数据的流。完成后拨打close()
,是否需要在句柄上调用delete
或close()
执行清理?
例如:
mFileStream = new std::ofstream(LogPath.c_str(), std::ios::trunc);
...
mFileStream->Close();
//delete mFileStream?
我的直觉是肯定的,因为我已经分配了它,但我不确定我在哪里阅读它。任何人都可以澄清吗?
答案 0 :(得分:8)
是的,你必须这样做。在C ++中,您必须将new
和delete
配对。
虽然,在这样一个简单的情况下你不需要,你可以在堆栈上分配你的对象并为你销毁它,强烈建议这样做(更快更安全):
{ // enclosing scope (function, or control block)
ofstream mFileStream(LogPath.c_str(), std::ios::trunc);
...
mFileStream.close(); // mFileStream is not a pointer any more, use the "." operator
// mFileStream destroyed for you here. "close" may even be called for you.
}
小记:它是close
,带有一个小“c”。
答案 1 :(得分:0)
分配有new
的所有对象必须具有相应的delete
以避免泄露。 new[]
和delete[]
也是如此(这些恰好是单独的运算符,BTW)。
作为J.N.指出,在上面的代码示例中,您不妨使用堆栈并避免运算符new / delete。如果流的使用仅限于某些明确定义的范围,则无需在免费存储(堆)上创建对象。
您实际上不需要的是对close
的调用。文件流在销毁时已经关闭(在destuctor中),所以可以省略它。事实上,这是使用fopen / fclose上的文件流对象的一大优势,我们可以在这里看到:Do I need to manually close an ifstream?
此外,如果您使用C ++,就像Stroustrup鼓励强烈遵守他的RAII习惯用法一样,您通常希望避免编写需要手动调用删除的代码。目前这可能有点过头,但我们在C ++ 11中提供了智能指针,如shared_ptr
和unique_ptr
,它们会自动为我们销毁对象:
shared_ptr<ofstream> output_stream(new ofstream(...));
// ^^ This will not leak and the file will gracefully close
// when 'output_stream' is destroyed. It makes the need to
// call both delete and close unnecessary.
如果你冒险进入C ++异常处理领域,你会发现使用析构函数自动为你清理资源不仅方便,而且对于安全和正确编码非常重要。