C++에서 메시지와 함께 예외 발생
- 표준 C++ 예외를 사용하여 메시지와 함께 예외 발생 - 잘못된 인수
- 표준 C++ 예외 - 중첩 예외를 사용하여 메시지와 함께 예외 발생
- 런타임 오류를 사용하여 C++에서 메시지와 함께 예외 발생
- 결론
이 기사에서는 C++에서 변수 메시지로 예외를 발생시키는 방법을 설명합니다. 예외 throw는 충돌이나 오버플로를 방지하기 위해 프로그램 제어를 전환하는 프로세스입니다.
문제가 발생할 수 있는 프로그램 내부에 예외 throw를 배치하여 실행됩니다. C++에는 몇 가지 예외 처리 키워드가 있지만 이 기사에서는 변수 메시지를 사용하여 예외를 throw하는 방법을 살펴봅니다.
표준 C++ 예외를 사용하여 메시지와 함께 예외 발생 - 잘못된 인수
이 프로그램은 C++의 표준 예외에서 유효하지 않은 인수
예외를 사용하여 변수 메시지와 함께 예외를 발생시킵니다.
패키지 가져오기
이 프로그램은 표준 C++ 예외를 포함하는 stdexcept
와 입력 및 출력 작업을 위한 iostream
의 두 가지 가져오기 패키지를 사용합니다.
예외를 던지는 방법
이 프로그램은 입력으로 제공된 두 숫자를 비교하는 함수를 정의하고 음수 입력이 발생하면 예외를 발생시킵니다. 여기서는 표준 예외 std::invalid_argument
가 사용됩니다.
이 프로그램에서 메소드 compare
는 두 개의 정수 값 var_a
및 var_b
를 매개변수로 사용하여 정의됩니다. 이것은 if
를 사용하여 음수(a, b 또는 둘 다)를 확인하고 그렇다면 예외를 발생시킵니다.
if (var_a < 0 || var_b < 0) {
throw std::invalid_argument("Negative value encountered");
주요 방법
main
메서드는 try-catch
예외 키워드를 사용하여 유효한 예외를 throw합니다.
예외 처리는 try
블록 내에서 compare
메서드를 호출하여 실행됩니다. 입력 (-1,3)
이 음수이므로 try
블록은 인수를 catch
블록으로 보내 변수 메시지와 함께 예외를 발생시키고 메시지를 인쇄합니다.
#include <iostream>
#include <stdexcept>
using namespace std;
int check_neg(int var_a, int var_b) {
if (var_a < 0 || var_b < 0) {
throw std::invalid_argument("Negative value encountered");
}
return 0;
}
int main() {
try {
compare(-1, 3);
} catch (const std::invalid_argument& e) {
std::cout << "booh!";
}
}
출력:
booh!
--------------------------------
Process exited after 0.006709 seconds with return value 0
Press any key to continue . . .
표준 C++ 예외 - 중첩 예외를 사용하여 메시지와 함께 예외 발생
예외는 서로 중첩되어 여러 예외 메시지를 연속적으로 표시할 수 있습니다. 이 섹션의 프로그램은 오류 메시지를 중첩된 예외로 래핑한 다음 각 발생 시 변수 메시지와 함께 예외를 발생시키고 함께 표시합니다.
패키지 가져오기
이 프로그램에서 사용되는 가져오기 패키지는 다음과 같습니다.
iostream
stdexcept
exception
string
fstream
회원 방법
프로그램에는 print_exception
, open_file
및 run
의 세 가지 멤버 함수가 있습니다.
방법 print_exception
:
여기에는 std
예외를 포착하는 std::exception& ex
와 값 0으로 초기화되는 정수 변수 stage
라는 두 개의 공개 매개변수가 있습니다. 메서드 내에서 첫 번째 줄 std::cerr
은 Encountered Exception:
이라는 오류 메시지를 인쇄하는 데 사용되지만 std::string(level,'')
을 사용하여 중첩 수준에 배치됩니다.
오류 메시지 다음에는 ex.what
이 옵니다. 여기서 ex
는 std::exception
의 개체이고 ex.what
은 발생한 오류에 대한 설명 문자열을 반환합니다.
try
블록은 std::rethrow_if_nested(e)
를 사용하여 예외를 throw하지만 std
개체 ex
가 중첩된 예외에서 파생되는 경우에만 이 프로그램에서 수행합니다.
catch
블록은 std
개체 nestedException
을 사용하여 stage
값을 1로 증가시키면서 재귀적으로 자신을 다시 호출합니다. catch(...)
메서드는 모든 예외를 포착합니다.
void print_exception(const std::exception& ex, int level = 0) {
std::cerr << std::string(level, ' ') << "Encountered Exception: " << ex.what()
<< '\n';
try {
std::rethrow_if_nested(ex);
} catch (const std::exception& nestedException) {
print_exception(nestedException, stage + 1);
} catch (...) {
}
}
위의 코드에서 일어나는 일은 예외에 대한 설명 문자열을 인쇄하려고 시도한다는 것입니다. 함수가 중첩된 것을 찾으면 보유하고 있는 예외에 대한 설명을 인쇄하기 위해 재귀합니다.
메소드 open_file
:
이 함수에는 std::string& s
라는 단일 문자열 매개변수가 있어 std::string
개체를 생성하고 여기에 별칭 s
를 전송합니다.
try-catch
블록은 파일 읽기를 시도하고 파일을 로드할 수 없을 때 예외를 포착하고 중첩된 함수로 래핑합니다.
void open_file(const std::string& s) {
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch (...) {
std::throw_with_nested(std::runtime_error("Couldn't open " + s));
}
}
메서드 실행()
:
void run()
메서드는 try
블록 내에서 open_file
메서드를 호출합니다. catch(...)
블록은 std::throw_with_nested
를 통해 발생하는 모든 예외를 포착합니다.
현재 처리 중인 예외와 e
를 결합하는 예외를 발생시킵니다.
현재 처리 중인 예외는 외부 예외가 되고 e
는 중첩 예외가 됩니다. "run() failed"
는 인쇄된 최종 메시지입니다.
void run() {
try {
open_file("nonexistent.file");
} catch (...) {
std::throw_with_nested(std::runtime_error("run() failed"));
}
}
메서드 int main()
:
main
메서드는 try
블록 내에서 run()
함수를 호출하고 catch
블록 내에서 프로그램은 e
를 매개 변수로 전달하면서 print_exception
메서드를 호출합니다.
가변 메시지로 예외를 발생시키는 함수를 실행하고, 중첩된 형식으로 포착된 예외를 인쇄하고, 각 예외 발생과 함께 사용자 지정 메시지를 표시합니다.
int main() {
try {
run();
} catch (const std::exception& e) {
print_exception(e);
}
}
전체 코드:
#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
void print_exception(const std::exception& ex, int stage = 0) {
std::cerr << std::string(stage, ' ') << "Encountered Exception: " << ex.what()
<< '\n';
try {
std::rethrow_if_nested(ex);
} catch (const std::exception& nestedException) {
print_exception(nestedException, stage + 1);
} catch (...) {
}
}
void open_file(const std::string& s) {
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch (...) {
std::throw_with_nested(std::runtime_error("Couldn't open " + s));
}
}
void run() {
try {
open_file("nonexistent.file");
} catch (...) {
std::throw_with_nested(std::runtime_error("run() failed"));
}
}
int main() {
try {
run();
} catch (const std::exception& e) {
print_exception(e);
}
}
출력:
exception: run() failed
exception: Couldn't open nonexistent.file
exception: basic_ios::clear
--------------------------------
Process exited after 0.05326 seconds with return value 0
Press any key to continue . . .
런타임 오류를 사용하여 C++에서 메시지와 함께 예외 발생
사용자 지정 클래스를 사용하여 소스 파일의 경로 및 이 오류가 발생한 줄과 함께 변수 메시지와 함께 예외를 throw할 수 있습니다.
이 프로그램은 사용자 정의 클래스와 매크로를 사용하여 std::runtime_error
를 사용하여 설명 문자열에 변수 메시지를 출력합니다.
패키지 가져오기
이 프로그램에는 다음과 같은 4개의 가져오기 패키지가 필요합니다.
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
공개 클래스
이 프로그램은 생성자 클래스를 사용하여 변수 메시지와 함께 예외를 발생시키고 공용 생성자가 std::runtime_error
를 사용하여 호출될 때 해당 사용자 정의 메시지를 설명 문자열로 표시합니다.
코드 스니펫의 첫 번째 라인은 my_exception
클래스와 새 runtime_error
객체를 생성합니다. 이와 함께 설명 변수 문자열을 전달하는 데 사용되는 문자열 개체 msg
가 전역 범위로 만들어집니다.
생성자 클래스 my_exception
은 설명 문자열을 전달하는 std
문자열 객체 arg
, 파일 이름을 저장하는 데이터 유형 char의 포인터 객체 *file
및 정수 변수의 세 가지 매개변수로 초기화됩니다. 예외가 발생한 라인을 저장하는 라인.
이 개체가 호출될 때 출력을 표시하기 위해 std::ostringstream
을 사용하여 문자열 출력 개체가 생성됩니다. 마지막으로 이 개체는 msg
변수에 저장됩니다.
소멸자 ~my_exception()
은 return msg.c_str();
을 사용하여 변수 msg
를 null로 끝나는 문자열로 반환합니다.
class my_exception : public std::runtime_error {
std::string msg;
public:
my_exception(const std::string &arg, const char *file, int line)
: std::runtime_error(arg) {
std::ostringstream o;
o << file << ":" << line << ": " << arg;
msg = o.str();
}
~my_exception() throw() {}
const char *what() const throw() { return msg.c_str(); }
};
매크로와 예외 던지기
여기서 매크로는 #define throw_line(arg)
을 사용하여 정의됩니다. throw_line()
을 호출하면 my_exception(arg, __FILE__, __LINE__)
이 발생합니다.
메서드 void f()
는 매크로 throw_line
을 호출하고 Oh no!
메시지를 전달합니다.
#define throw_line(arg) throw my_exception(arg, __FILE__, __LINE__);
void f() { throw_line("Oh no!"); }
주요 방법
메인 메서드는 try
블록 내에서 f()
메서드를 호출하여 변수 메시지와 함께 예외를 발생시킵니다. 그러면 메시지 블록이 my_exception
메서드로 전달됩니다.
catch
블록 내에서 runtime_error
객체 ex
가 생성되며 ex.what()
을 사용하여 설명 문자열을 호출합니다.
설명 문자열이 호출되면 my_exception
생성자 내부에서 ostream
개체가 호출되고 메시지 변수와 함께 파일 이름 및 오류 줄을 반환합니다.
int main() {
try {
f();
} catch (const std::runtime_error &ex) {
std::cout << ex.what() << std::endl;
}
}
전체 코드:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
class my_exception : public std::runtime_error {
std::string msg;
public:
my_exception(const std::string &arg, const char *file, int line)
: std::runtime_error(arg) {
std::ostringstream o;
o << file << ":" << line << ": " << arg;
msg = o.str();
}
~my_exception() throw() {}
const char *what() const throw() { return msg.c_str(); }
};
#define throw_line(arg) throw my_exception(arg, __FILE__, __LINE__);
void f() { throw_line("Oh no!"); }
int main() {
try {
f();
} catch (const std::runtime_error &ex) {
std::cout << ex.what() << std::endl;
}
}
출력:
D:\c++\std-exceptions\8.cpp:23: Oh no!
--------------------------------
Process exited after 0.006875 seconds with return value 0
Press any key to continue . . .
결론
이 문서에서는 변수 메시지를 사용하여 예외를 throw한 다음 예외가 throw될 때 메시지를 표시하는 다양한 방법을 설명합니다.
이 문서가 가변 메시지로 예외를 throw하는 방법을 배우고 실제 시나리오에서 사용할 수 있도록 도움이 되었기를 바랍니다.