#include <iostream>



#include <cassert>



int main(void)

{



//오늘 하는거가 흔히들 예외처리라고 부르는겁니다. 


//예외를 처리하는 방법이 많이 쓰는 법이 한가지밖에 없었죠.


//만약에 ~면 ~해라 


//예외상황이 발생했을때 문제가 발생하지않도록 적절히 처리하는거 



//c++에 오면서 예외처리가 문제가 발생하지않도록 더 안정적으로, 효율적으로 관리할수있게하는 문법이 나옴. 


//가장 많이 쓰는것부터 한번 보겠습니다.


//저 헤더 쓰면 이 함수 사용할수있음. 

//assert()


//예외처리(Exception)

//assert(0);  //() 안에 조건문 넣는데. 그냥 참1 거짓0을 바로 넣는다. 

//0이면 무조건 뻗고 

//1이면 안뻗고 제대로 실행되고 


//실제로 저런건 게임 출시할때 예외처리를 저런식으로 뻗게만드는 경우는 거의 없다. 유저들이 화가 날수있고 안좋아할수 예민할수있어서


//에러난것처럼 뻗는것보단 블루스크린이 뜨는게 낫다.

//윈도우관리를 못해서 뻗었다라고 착각할수있으니까. 


//assert는 개발하는 도중에 넣는거다. 오류를 눈치못챌수가 있고 눈치못채고 넘어갈수있어서 프로그래머들이 개발 중에 넣는 것이다.


int* pInt = new int;

assert(pInt != nullptr);

//if (pInt != nullptr)

*pInt = 10;



  //만약에 뻗게는 안하고싶으면....


  //() 안에 파일을 출력시켜주는방식으로 ...



if (pInt != nullptr)

{

delete pInt;


pInt = nullptr;


}


///////////

//우아한 예외처리 

//우아한 구조 

//그런 방법이 있다.


//그게 뭐냐면...,


//try~(throw)~catch 구문


//써보면 그리 우아하진않아요

//예외처리는 항상 지저분해 

//깔끔하게 써도 지저분안할수가 없어요.



//트라이 구문... 영어로 하면 코드 블럭

//Code Block

//동적할당한 공간도 메모리 블록 


//try : 예외가 발생할 요지가 있는 구문을 묶는거 

try {


//예외가 발생하는 상황

//예외를 던진다.

// throw : 예외를 던짐. 예외가 발생했다라는걸 던져주는거 예외가 발생했다라고 던지는것뿐. 예외조건을 적는게아니다!  

throw 1; //걍 정수 하나를 던져봅시다.



}

//정수를 받는 catch문 

catch (int _val) //켓치문에서 정수를 던진 애를 받는다. 

{


std::cout << "catch : " << _val << std::endl;




}




try {


//예외가 발생하는 상황

//예외를 던진다.

// throw : 예외를 던짐. 예외가 발생했다라는걸 던져주는거 예외가 발생했다라고 던지는것뿐. 예외조건을 적는게아니다!  

throw 100; //걍 정수 하나를 던져봅시다.



}

//정수를 받는 catch문 

catch (int _val) //켓치문에서 정수를 던진 애를 받는다. 

{


std::cout << "catch : " << _val << std::endl;




}




try {


//예외가 발생하는 상황

//예외를 던진다.

// throw : 예외를 던짐. 예외가 발생했다라는걸 던져주는거 예외가 발생했다라고 던지는것뿐. 예외조건을 적는게아니다!  

throw 100.234f; //걍 정수 하나를 던져봅시다.



}

//정수를 받는 catch문 

catch (int _val) //켓치문에서 정수를 던진 애를 받는다. 

{


std::cout << "catch  int : " << _val << std::endl;




}

catch (float _val)

{




std::cout << "catch float : " << _val << std::endl;



}



////////////////////////////



int iVal = 5;

float fVal = 3.5f;

char cVal = 'a';



try {


//예외가 발생하는 상황

//예외를 던진다.

// throw : 예외를 던짐. 예외가 발생했다라는걸 던져주는거 예외가 발생했다라고 던지는것뿐. 예외조건을 적는게아니다!  

throw "Exception"; //걍 정수 하나를 던져봅시다.

//위에서 내리는 명령 ... 공문 .... 

if (iVal < 5)

{


std::cout << "File : " << __FILE__ << std::endl;

std::cout << "Line : " << __LINE__ << std::endl;

std::cout << "iVal is under 5" << std::endl;


}



//던질 상황을 만들어줘야된다.

int* pI2;

if (pI2 == nullptr)

throw "pI == nullptr";



// if (iVal == 10)

// {

//

// std::cout << "File : " << __FILE__ << std::endl;

//std::cout << 



//}


throw iVal;



}

//정수를 받는 catch문 

catch (int _exception) //켓치문에서 정수를 던진 애를 받는다. 

{


// std::cout << "catch  int : " << std::endl;


std::cout << "File : " << __FILE__ << std::endl;

std::cout << "Line : " << __LINE__ << std::endl;

std::cout << "catch  int : " << _exception << std::endl;




}

catch (float  _exception)

{




//std::cout << "catch float : " << std::endl;

std::cout << "catch float : " << _exception << std::endl;




}

catch (const char* const _exception)

{




// std::cout << "catch char* : " << std::endl;

// std::cout << "File : " << __FILE__ << std::endl;

//std::cout << "Line : " << __LINE__ << std::endl;

std::cout << "catch char* : " << _exception << std::endl;



}







return 0;

}