
- std::exception 의 파생 클래스
- logic_error
- invalid_argument
- 부적절한 argument value | std::bitset::bitset, std::stoi, std::stof
- domain_error
- 루트안에 음수를 넣었다거나 하는, 논리상의 도메인을 벗어난 에러, 스탠다드 라이브러리는 이 에러를 출력하지 않음, math_errhandling 같은 자체 에러가 있음. 그러나 boost.math 같은 써드파티 라이브러리에서는 이 에러를 출력함 | boost.math
- length_error
- 객체의 한계를 벗어난 시도를 했을때 일어남 | std::basic_string, std::vector::reserve
- out_of_range
- 정의된 범위에서 벗어난 원소에 접근하는 시도를 했을때 일어남 | std::bitset, std::basic_string(by std::stoi, std::stod), std::vector::at, std::map::at
- future_error
- 스레드 라이브러리에서 출력하는 예외 | std::future, std::promise
- invalid_argument
- runtime_error
- range_error
- 연산 결과가 destination type으로 변환될 수 없을 때 | std::wstring_convert::from_bytese, std::wstring_convert::to_bytes
- overflow_error
- 연산 결과가 destination type의 크기를 벗어날 때 | std::bitset::to_ulong. std::bitset::to_ullong
- underflow_error
- arithmetic underflow, 연산 결과가 원하지 않는 floating-point value를 포함할때 | boost.math
- regex_error
- regex 객체를 위한 에러
- system_error
- ios_base::failure
- 입출력에 실패했을 때
- filesystem::filesystem_error
- 파일시스템 라이브러리에 포함된 에러, public memeber function으로 path1 과 path2가 있음
- ios_base::failure
- tx_exception
- atomic_cancle 키워드와 Transactional memory와 관련이 있음
- nonexistent_local_time
- std::chrono 와 관련된 변환 에러
- abiguous_local_time
- std::chrono 와 관련된 변환 에러
- format_error
- range_error
- bad_optional_access
- std::optional::value에서 출력, optioanl object가 값을 가지고 있지 않을때 출력 | std::optional::value
- bad_typeid
- bad_cast
- bad_any_cast
- bad_weak_ptr
- bad_function_call
- bad_alloc
- bad_array_new_length
- bad_exception
- ios_base::failure
- bad_variant_access
- logic_error
- Example.1 함수 호출은 Stack 이다.
// Example.1 LIFO
#include <iostream>
using namespace std;
class Object {
static int count;
int ID;
public:
Object() {
ID = count++;
cout << "Oject(" << ID << ") created." << endl;
}
~Object() { cout << "Object(" << ID << ") perished" << endl; }
};
int Object::count = 1;
auto main() ->int {
Object ob1;
{
Object ob2;
}
Object ob3;
}
/*
Oject(1) created.
Oject(2) created.
Object(2) perished
Oject(3) created.
Object(3) perished
Object(1) perished
*/
- Example.2 일단 한번 에러가 던져지면, try문을 빠져나가기 때문에, 다른 에러는 잡을 수 없다.
// Example.2 예외 던지기
#include <iostream>
#include <string>
#include <vector>
class Person {
std::string firstname;
std::string lastname;
int arbitrarynumber;
public:
Person() : firstname(""), lastname(""), arbitrarynumber(-1) {}
Person(std::string first, std::string last, int arbitrary)
: firstname(first), lastname(lastname), arbitrarynumber(arbitrary) {
if (arbitrarynumber == 0) {
throw std::invalid_argument("Cannot be Zero : arbitrary number");
}
}
std::string GetName() const { return firstname + " " + lastname; }
int GetNum() const { return arbitrarynumber; }
};
auto main() ->int {
std::vector<int> v;
v.push_back(1);
try {
Person Nakamura("Nakamura", "Shinichiro", 0);
int j = v.at(99);
}
catch (std::out_of_range& e) {
std::cout << " out of range exception " << e.what();
}
catch (std::exception& e) {
std::cout << e.what();
}
}
/*
Cannot be Zero : arbitrary number
*/
- Stack Unwinding : Example.3
- When an exception is thrown, If in a try, everything local to try block goes out of scope
- Destructors go off
- Control goes to the catch
- If not, everything local to the function goese out of scope
- control returns to where that function was called from
- Recurse to "if in a try" above
- If you get all the way out of main(), the user gets a dialog
- But it's more interesting when you end up in a catch
- 어쨋든, try 문도 스코프로 봐야하기 때문에, try문에서 생성된 객체는 스코프를 벗어나기 전에. 소멸자가 호출되어야 한다.
- (with RAII) 메모리 할당->생성자 호출-> 예외 발생 -> 소멸자 호출 -> 스코프 벗어나기 -> 예외 출력
- (without RAII) 메모리할당->생성자 호출 -> 예외 발생 -> 스코프 벗어나기 -> 예외출력 (소멸자 호출 안함은 메모리릭을 의미)
- When an exception is thrown, If in a try, everything local to try block goes out of scope
C++ RAII(Resource Acquisition Is Initialization)의 해석
RAII라는 이름 자체에 대한 "꿈보다 해몽"
occamsrazr.net
// Example.3 Stack Unwinding
#include <iostream>
#include <string>
#include <vector>
class Person {
std::string firstname;
std::string lastname;
int arbitrarynumber;
public:
Person() : firstname(""), lastname(""), arbitrarynumber(-1){}
Person(std::string first, std::string last, int arbitrary)
: firstname(first), lastname(lastname), arbitrarynumber(arbitrary){
if(arbitrarynumber == 0){
throw std::invalid_argument("Cannot be Zero : arbitrary number");
}
}
~Person(){
std::cout << firstname << " " << lastname << " Die" << std::endl;
}
std::string GetName() const{ return firstname + " " + lastname; }
int GetNum() const{ return arbitrarynumber; }
};
class Noise {
std::string SoundIMake;
public:
Noise(std::string sim) : SoundIMake(sim){
std::cout << "Constructing Noise " << SoundIMake << std::endl;
};
~Noise(){
std::cout << "Destructing Noise " << SoundIMake << std::endl;
};
};
auto main() ->int{
using namespace std;
vector<int> v;
Noise n1("beep 1");
try{
Noise n2("boop 2"); // 이녀석의 소멸자는 호출된다.
Person Obama("Obama", "BinLaden", 0); //이녀석의 소멸자는 호출되지 않는다.
int j = v.at(99); // 이 구문은 실행조차 되지 않는다. Person Obama의 생성자에서 먼저 에러를 던지기 때문에
}
catch(out_of_range& e){
cout << " ouf of range exception " << e.what() << endl;
}
catch(exception& e){
cout << e.what() << endl;
}
}
/*
Constructing Noise beep 1
Constructing Noise boop 2
Destructing Noise boop 2
Cannot be Zero : arbitrary number
Destructing Noise beep 1
*/
'C++' 카테고리의 다른 글
Type Category Testing_1(형 카 검-내장타입) (0) | 2022.07.03 |
---|---|
[C++] Return Value Optimization(RVO) (0) | 2021.01.04 |
[레거시 코드] 함수포인터, 보이드포인터 (0) | 2020.12.03 |
[C++] 범위기반 for 루프를 위한 클래스 템플릿 최소 구현 (0) | 2020.11.16 |
스마트 클래스 (0) | 2020.11.15 |