를 close()
사용할 때 수동으로 전화해야 std::ifstream
합니까?
예를 들어, 코드에서 :
std::string readContentsOfFile(std::string fileName) {
std::ifstream file(fileName.c_str());
if (file.good()) {
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
return buffer.str();
}
throw std::runtime_exception("file not found");
}
file.close()
수동으로 전화 해야합니까? 파일을 닫기 위해 RAII 를 ifstream
사용 해서는 안 됩니까?
답변
아니
이것이 RAII의 목적입니다. 소멸자가 그 일을하도록하십시오. 수동으로 닫는 데 아무런 해가 없지만 C ++ 방식이 아니며 클래스를 사용하여 C로 프로그래밍합니다.
함수가 끝나기 전에 파일을 닫으려면 항상 중첩 범위를 사용할 수 있습니다.
표준 (27.8.1.5 클래스 템플릿 basic_ifstream) 에서 실제 파일 핸들을 보유 ifstream
하는 basic_filebuf
멤버 로 구현됩니다 . ifstream 객체가 소멸 될 때 멤버를 소멸자로 호출하도록 멤버로 유지됩니다 basic_filebuf
. 그리고 표준 (27.8.1.2)에서 그 소멸자는 파일을 닫습니다.
virtual ˜basic_filebuf();
효과 : class의 객체를 파괴합니다
basic_filebuf<charT,traits>
. 전화close()
.
답변
파일을 닫아야합니까?
아니
파일을 닫아야합니까?
다릅니다.
파일이 올바르게 닫히지 않을 경우 발생할 수있는 오류 조건에 관심이 있습니까? setstate(failbit)
실패하면 전화를 끊어야합니다. 소멸자는 RAIIclose()
때문에 자동으로 호출 하지만 객체가 더 이상 존재하지 않으므로 페일 비트를 테스트하는 방법을 남기지 않습니다.
답변
@Martin에 동의합니다. 파일에 쓰면 데이터가 여전히 버퍼에 있고 close()
호출 될 때까지 파일에 쓰지 않을 수 있습니다 . 수동으로 수행하지 않으면 오류가 있는지 여부를 알 수 없습니다. 사용자에게 오류를보고하지 않는 것은 매우 나쁜 습관입니다.
답변
아니요, ifstream
소멸자가 자동으로 수행합니다 . 수동으로 호출해야하는 유일한 이유는 fstream
인스턴스가 오래 지속되는 클래스 인스턴스의 멤버 변수 인 경우와 같이 범위가 넓기 때문입니다.
답변
소멸자가 작업을 수행하도록 허용 할 수 있습니다. 그러나 RAII 객체와 마찬가지로 수동으로 close를 호출하면 차이가 생길 수 있습니다. 예를 들면 다음과 같습니다.
#include <fstream>
using std::ofstream;
int main() {
ofstream ofs("hello.txt");
ofs << "Hello world\n";
return 0;
}
파일 내용을 씁니다. 그러나:
#include <stdlib.h>
#include <fstream>
using std::ofstream;
int main() {
ofstream ofs("hello.txt");
ofs << "Hello world\n";
exit(0);
}
하지 않습니다. 프로세스가 갑자기 종료되는 드문 경우입니다. 충돌하는 프로세스도 비슷할 수 있습니다.