16.예외처리등 기타
예외 처리 (Exception Handling)
특수한 상황의 처리를 위해 사용
프로그램은 이러한 특수한 상황에 대해 특수한 처리를 해 주어야 함
특수한 상황이란
리소스 부족 / missing
잘못된 연산
범위의 위반 (out of bound)
오버 플로우 / 언더플로우
예외처리 0으로 나눔
try{
if(total == 0){
throw 0; //throw exception
avg = sum / total; // not execitr if total == 0
}
catch (int &ex){
cerr << "Can't divide by zero" << endl;
}
cout << "program continues" << endl;
// cerr은 에러 로깅을 위한 출력
Files, Streams and I/O
전역 스트림 객체
cin → 표준 입력 스트림, istream의 인스턴스
cout → 표준 출력 스트림, ostream의 인스턴스
cerr → 표준 에러 스트림, ostream의 인스턴스
clog → 표준 로그 스트림, ostream의 인스턴스
전역 객체
Main함수의 실행 이전에 초기화 되는 객체들
관련 헤더 파일
iostream → 스트림으로의 형식화된 입출력
fstream → 파일 스트림으로의 입출력
iomanip → 스트림으로의 입출력 형식을 조작
관련 클래스
ios → 기본적인 입출력 연산 지원, 대부분 다른 클래스의 기본 클래스
ifstream → 파일 기반 스트림의 입력 가능(파일읽기)
ofstream → 파일 기반 스트림의 출력 기능(파일 쓰기)
fstream → 파일 기반 스트림의 입출력 기능(i/ofstream의 파생 클래스)
stringstream → 스트링으로의 입출력 가능
스트림 조작자(Stream Manipulators)
입력 및 출력 형식을 조절하기 위한 다양한 기능을 제공
ex : 화면에 보이는 소수점 자리수 결정
효과가 지속되는 범위가 기능마다 다름을 주의
멤버 함수 형식을 사용하거나 조작자 형식으로 사용 가능
#include <iomanip>
cout.width(10); // member function call
cout << setw(10); // manipulator
Formatting Field width, align and fill
필드 너비, 정렬과 채움
실수형 자료 형식을 표시하는 기본값
→ setw → 설정되지 않음
→ left → field width가 없을때, right → field width가 주어졌을 때
→ fill → 설정되지 않음(공백은 빈 문자로 표기)
몇몇 조작자들은 스트림에 들어온 바로 다음 데이터에만 적용됨
Formatting Floating Point
실수형 자료형의 형식화
기본값으로 되돌리기
cout << resetiosflags(ios::floatfield);
Input File
//fstream 객체의 파일의 연결
frsteam in_file("../myfile.txt", ios::in);
//"파일위치", "옵션(읽기)"
fstream in_file(".._myfile.txt", ios:in | ios:binary};
//바이너리 모드로 열기
Output file
파일 복사 예제
char by char
ifstream in_file("../myfuile.txt"};
ostream out_file("../copy.txt"};
if(!in_file){
cerr << "File open error" << endl;
return 1;
}
if(!out_file){
cerr <"File create error" << endl;
return 1;
}
char c:
while(int_file.get(c)){
out_file.put(c);
}
in_file.close();
out.file.close();
스마트 포인터
Raw pointer의 문제점
스마트 포인터란
Ownership과 RAll
RAll : Resource Acquisition Is Initialization
객체의 생애주기를 안전하게 관리하는 기법
Resource의 획득
→ Heap 메모리 할당
→ 파일 열기, DB 연결등
Is Initialization
→ Resource는 생성자에서 획득
Resource의 해제
→ Heap 메모리 해제
→ 파일 닫기, DB 연결 종료 등
→ 소멸자에서 수행
스마트 포인터들
→ unique_ptr
#include <iostream>
#include <memory>
int main(){
{
std::unique_ptr<int> p1{new int{100}};
int* int_ptr{nullptr};
std::cout << p1 << std::endl;
// int_ptr = p1;
std::cout << *p1 << std::endl; //00C0D2C0
int_ptr = p1.get(); //not good, but possible
std::cout << p1.get() << std::endl;
p1.reset();
if(p1){
std::cout << *p1 << std::endl;
}
}
return 0;
}
→ shared_ptr
→ weak_ptr
custom 소멸자
스마트 포인터가 소멸될 때의 로직을 구현하고 싶을 경우 사용
make_unique, make_shared는 이러한 경우에는 사용 불가능
void my_deleter(Some_Class *raw_pointer){
//필요한 로직 작성
delete raw_pointer;
}
int main(){
{
std::shared_ptr<Some_Class> ptr{ new Some_Class(), my_deleter};
}
return 0;
}
//Custom deleters 예시
class Test{
private:
int data;
public:
Test(int data) : data{data}
{std::cout << "Test constructor" << std::endl;}
~Test()
{std:cout << "Test destructor" << std::endl;}
};
void my_deleter(Test *raw_pointer){
std::cout << "Custom destructor" << std::endl;
delete raw_pointer; //이 명령으로 ~Test()호출
}
int main(){
{
std::shared_ptr<Test> ptr{new Test{100}, my_deleter};
} //자동 해제
return 0;
}