Standard Exception Class Hierarchy
- runtime_error
- logic_error
Try/Catch/Throw 기본 형태
try {
// protected code
throw e;
}
catch (ExceptionName e1) {
// catch block
}
catch (ExceptionName e2) {
// catch block
}
catch (ExceptionName e3) {
// catch block
}
<예시코드>
#include <iostream>
using namespace std;
int main() {
int number1{ 5 };
int number2{ 0 };
try {
if (number2 == 0)
throw number2;
else
cout << number1 / number2 << endl;
}
catch (int) {
cout << "error: division by zero " << endl;
}
return 0;
}
* catch 구문에서 자료형 일치해야함!!!
Registering Handlers
#include <exception>
terminate_function set_terminate (terminate_function func);
- General Handler
<예시코드>
#include <iostream>
#include <exception>
using namespace std;
void MyHandler() {
cout << "My handler" << endl;
exit(EXIT_FAILURE);
}
int main() {
int number1{ 5 };
int number2{ 0 };
set_terminate(MyHandler);
try {
if (number2 == 0)
throw number2;
else
cout << number1 / number2 << endl;
}
catch (char) {
cout << "error: char " << endl;
}
return 0;
}
- Multiple Catch Blocks
-> catch 구문이 여러개 있다면, 자료형에 맞춰 자동으로 구현된다.
- Nested Exception Handling (re - throw)
-> try 블록은 try/catch 블록을 포함할 수 있다.
* ERROR
- try블록과 그것에 상응하는 catch 핸들러 사이, 혹은 catch 핸드러 사이에 코드를 넣는 것은 오류
- 각각의 catch 핸들러는 하나의 매개변수만 가질 수 있다.
- 단일의 try block에서 같은 타입의 multiple catch handlers는 컴파일 오류이다.
- 예외가 다뤄진 후 , throw 구문 바로 뒤 명령줄로 돌아가게 되면 로직 오류가 있을 수 있다.
Stack Unwinding
#include <iostream>
#include <exception>
using namespace std;
void func3() {
cout << "f3 enter" << endl;
throw 1;
cout << "f3 exit" << endl;
}
void func2() {
cout << "f2 enter" << endl;
func3();
cout << "f2 exit" << endl;
}
void func1() {
cout << "f1 enter" << endl;
try {
func2();
} catch (int value) {
cout << "catch in f1" << endl;
}
cout << "f1 exit" << endl;
}
int main() {
func1();
return 0;
}
장점 - 가독성 증진
단점 - 때때로 expensive stack unwinding 발생
Exception Type
1. primitive data types : throw keyword receives any primitive types.
2. c++ exception classes : a set of pre-defined exception types.
3. customized exception classes : usuers can define a customized types.
Constructors and Exception Handling
<예시코드 1>
#include <iostream>
using namespace std;
class myClass {
public:
myClass(const string& m) : data{ m } {//my의 data = "Data!"
cout << "constructor: " << data << endl;
}
myClass(const myClass& r) : data{ r.data + " (copy)" } {
cout << "Copy constructor: " << data << endl;
}
string print() const { return data; }
~myClass() { cout << "destructor: " << data << endl; }
private:
string data;
};
int main() {
try {
myClass my{ "Data!" };
throw my;
}
catch (myClass e) {//객체 e 생성 my -> e 데이터 복사 . 복사생성자
cout << e.print() << endl;
}
return 0;
}
<예시코드2>
#include <iostream>
using namespace std;
class myClass {
public:
myClass(const string& m) : data{ m } {
cout << "constructor: " << data << endl;
}
myClass(const myClass& r) : data{ r.data + " (copy)" } {
cout << "Copy constructor: " << data << endl;
}
string print() const { return data; }
~myClass() { cout << "destructor: " << data << endl; }
private:
string data;
};
int main() {
try {
myClass my{ "Data!" };
throw my;
}
catch (const myClass& e) { //my 소멸자
cout << e.print() << endl; // e.print() -> e소멸자
}
return 0;
}
Standard Exception Class
out_range{} -> const out_of_range& e
logic_error& e
exception& e
...
*예시코드 찾아보기
Custom Exception Class
#include <iostream>
#include <stdexcept>
using namespace std;
class DivideByZeroException : public runtime_error{
public:
DivideByZeroException() : runtime_error("Division by 0") {}
};
double quotient(int numerator, int denominator) {
if (denominator == 0)
throw DivideByZeroException();
return static_cast<double> (numerator) / denominator;
}
int main() {
int number1{ 5 };
int number2{ 0 };
try {
cout << quotient(number1, number2);
}
catch (const DivideByZeroException& e) {
cout << e.what() << endl;
}
return 0;
}
'Major S-T-U-D-Y > OOP2' 카테고리의 다른 글
Template (0) | 2024.05.22 |
---|---|
Abstraction & Encapsulation (0) | 2024.05.22 |