Language/C++

16.예외처리등 기타

아무키 2023. 12. 25. 13:00
반응형

예외 처리 (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;
}
반응형