当前位置:网站首页>First knowledge of exception
First knowledge of exception
2022-06-28 13:25:00 【GarryLau】
Types of exceptions that can be thrown ( in fact , You can throw any type ):
1. Basic and compound types ;
2. Class types
Use ( class ) The benefits of throwing objects as exceptions :
1. The class name of the object can convey information ;
2. Objects can store information , Include the string used to describe the exception .
( remarks : It is suggested that const Reference catch exception )
If there are uncaught exceptions , Will call the built-in terminate() function , In this function call abort() To terminate the program
Functions that do not throw lists can throw any exceptions . have noexcept Or empty throw list throw() The function of cannot throw any exceptions .
throw
yes C++ Key words of , This is the only way to throw an exception .
To throw an exception , Or take the initiative to use throw, Or it calls other contains throw Methods .
#pragma once
#include <iostream>
#include <stdexcept>
namespace test_exception {
auto testThrow() -> void {
int a = 10, b = 0;
try {
if(0 == b) {
throw std::runtime_error("divided 0");
}
else{
int c = a / b;
}
}
catch(std::runtime_error& e){
std::cerr << "exception occurs: " << e.what() << std::endl;
}
}
auto testWantThrow() -> void {
int a = 10, b = 0;
try {
int c = a / b; // try There is no... In the statement block throw, So no exception will be thrown
}
catch(...){
std::cerr << "exception occurs." << std::endl;
}
}
auto main() -> int {
std::cout << "testing exception_errorprocess..." << std::endl;
testThrow();
testWantThrow();
std::cout << "------------------------------" << std::endl;
return 0;
}
}
Output :
1. Exception example
#pragma once
#include <stdexcept>
#include <exception>
#include <iostream>
namespace test_exception {
float divide1(float a, float b) {
if(b == 0){
//throw "divided by zero.";
//throw std::invalid_argument("Divide by zero");
//throw std::exception();
throw 5;
}
return a / b;
}
float divide2(float a, float b) noexcept/*throw()*/{
if(b == 0){
//throw "divided by zero.";
throw std::invalid_argument("std::invalid_argument, Divide by zero!");
//throw std::exception();
//throw 5;
}
return a / b;
}
#if 1
float divide3(float a, float b) throw(int, std::invalid_argument){
// Indicates that only... Can be thrown int, std::invalid_argument Two types of exceptions
if(b == 0){
//throw "divided by zero."; // This type cannot throw
throw std::invalid_argument("std::invalid_argument, Divide by zero!"); // This type can be thrown
//throw std::exception(); // This type cannot throw
//throw 5; // This type can be thrown
}
return a / b;
}
#endif
auto catchSample1() -> void {
int a = 10;
int b = 0;
try {
std::cout << divide1(a, b) << std::endl;
}
catch(const char* e){
std::cout << e << std::endl;
}
catch(const std::invalid_argument& e){
std::cout << e.what() << std::endl;
}
catch(const std::exception& e){
// increase const Attributes do not affect the purpose of the match , That is, this sentence is related to std::exception& e Can match std::exception Exception of type
std::cout << "+++" << e.what() << "+++" << std::endl;
}
catch(int e){
std::cout << "catching integer\n";
}
catch(...){
// Wildcards that match all exception types at three points , You can use this technique to ensure that all possible exceptions are caught
std::cout << "unknow exception" << std::endl;
}
}
auto catchSample2() -> void {
int a = 10;
int b = 0;
std::cout << "entering catchSample2()...............\n";
try {
std::cout << divide2(a, b) << std::endl;
}
catch(const std::invalid_argument& e){
std::cout << e.what() << std::endl;
}
catch(...){
std::cout << "unknow exception" << std::endl;
}
std::cout << "exiting catchSample2()...............\n";
}
auto main() -> void {
std::cout << "testing exception......" << std::endl;
catchSample1();
catchSample2();
std::cout << "--------------------------------------\n";
}
}
float divide2(float a, float b) noexcept
It is defined to prohibit throwing exceptions , So when you divide by 0( Exception occurs ) At the time catchSample2()
No capture , It's left to the operating system ( It's usually called terminate()
).
The above program output :
__cplusplus: 201103
testing exception......
catching integer
entering catchSample2()...............
terminate called after throwing an instance of 'std::invalid_argument'
what(): std::invalid_argument, Divide by zero!
It should be noted that for the code like the above float divide3(float a, float b) throw(int, std::invalid_argument)
Throw list C++17 No longer support , So if you use C++17 The standard compiler will report the following error :error: ISO C++17 does not allow dynamic exception specifications
# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
2. Exception hierarchy

You need to be careful when catching exceptions in the class hierarchy :
1. When using polymorphism to catch exceptions , Be sure to capture by reference . Truncation can occur if exceptions are caught by value , The information of the object is lost .
2.catch Statements should appear in the order in which the restrictions are reduced ( Put the special in front 、 Usually placed in the back ). For example, if you want to capture invalid_argument
abnormal , Then you should invalid_argument
Put it in exception
front ; If invalid_argument
Put it in exception
Back then invalid_argument
Can never execute . See the following two examples for details :
#pragma once
#include <stdexcept>
#include <exception>
#include <iostream>
namespace test_exception {
float divide(float a, float b) {
if(b == 0){
throw std::invalid_argument("Divide by zero");
//throw std::exception();
}
return a / b;
}
auto catchSample() -> void {
int a = 10;
int b = 0;
try {
std::cout << divide(a, b) << std::endl;
}
catch(const std::invalid_argument& e){
std::cout << e.what() << std::endl;
}
catch(const std::exception& e){
std::cout << "+++" << e.what() << "+++" << std::endl;
}
catch(...){
std::cout << "unknow exception" << std::endl;
}
}
auto main() -> void {
std::cout << "testing exception......" << std::endl;
catchSample();
std::cout << "--------------------------------------\n";
}
}
The results are as follows :
__cplusplus: 201703
testing exception......
Divide by zero
--------------------------------------
The end.
#pragma once
#include <stdexcept>
#include <exception>
#include <iostream>
namespace test_exception {
float divide(float a, float b) {
if(b == 0){
throw std::invalid_argument("Divide by zero");
//throw std::exception();
}
return a / b;
}
auto catchSample() -> void {
int a = 10;
int b = 0;
try {
std::cout << divide(a, b) << std::endl;
}
catch(const std::exception& e){
std::cout << "+++" << e.what() << "+++" << std::endl;
}
catch(const std::invalid_argument& e){
std::cout << e.what() << std::endl;
}
catch(...){
std::cout << "unknow exception" << std::endl;
}
}
auto main() -> void {
std::cout << "testing exception......" << std::endl;
catchSample();
std::cout << "--------------------------------------\n";
}
}
The results are as follows :
__cplusplus: 201703
testing exception......
+++Divide by zero+++
--------------------------------------
The end.
3. Custom exception classes
It is suggested to start from the standard exception
Implement custom exception classes directly or indirectly .
When a piece of code throws an exception , The thrown value or object is copied ,
That is, construct a new object from the old object by using the copy constructor ; Replication is a must ,
Because the original object is higher in the stack , Therefore, it is possible to go out of scope before the exception is caught ( So it will be destroyed , The memory it occupies will be reclaimed ). therefore , If the object of the written class is thrown as an exception , Objects must be able to be copied , This means that if memory is dynamically allocated , Destructor must be written 、 Copy constructors and assignment operators .P296
Tips : Objects thrown as exceptions are copied at least once by value , Catching exceptions by reference avoids unnecessary duplication
#pragma once
#include <stdexcept>
#include <string>
#include <iostream>
#include <fstream>
namespace test_exception {
class FileError : public std::runtime_error {
public:
FileError(const std::string& filename): filename_(filename), msg_(""), std::runtime_error(""){
}
virtual const char* what() const noexcept override{
return msg_.c_str();}
protected:
std::string filename_, msg_;
};
class FileOpenError : public FileError {
public:
FileOpenError(const std::string& filename): FileError(filename){
msg_ = std::string("Unable to open ") + filename_;
}
};
class FileReadError : public FileError {
public:
FileReadError(const std::string& filename, int linenumber): FileError(filename), linenum_(linenumber){
msg_ = std::string("Exception occurs in file ") + filename_ + std::string(", line ") + std::to_string(linenum_);
}
protected:
int linenum_;
};
auto main() -> void {
std::cout << "testing exception......" << std::endl;
std::string filename("../doc/daisy.txt");
std::ifstream in_file(filename);
try {
if(in_file.fail()){
throw FileOpenError(filename);
}
std::string line;
int linenum = 0;
while(std::getline(in_file, line)){
linenum++;
std::cout << line << std::endl;
}
if(!in_file.eof()){
in_file.close();
throw FileReadError(filename, linenum);
}
}
catch(const FileOpenError& e){
std::cout << "Line: " << __LINE__ << ", " << e.what() << std::endl;
}
catch (const FileReadError& e){
std::cout << "Line: " << __LINE__ << ", " << e.what() << std::endl;
}
catch(...){
std::cout << "unknow error occurs." << std::endl;
}
in_file.close();
std::cout << "--------------------------------------\n";
}
}
daisy.txt
The content in :
D:/daisy/5547758_eea9edfd54_n.jpg
D:/daisy/5673551_01d1ea993e_n.jpg
D:/daisy/5673728_71b8cb57eb.jpg
D:/daisy/5794835_d15905c7c8_n.jpg
D:/daisy/5794839_200acd910c_n.jpg
The above code output :
__cplusplus: 201703
testing exception......
D:/daisy/5547758_eea9edfd54_n.jpg
D:/daisy/5673551_01d1ea993e_n.jpg
D:/daisy/5673728_71b8cb57eb.jpg
D:/daisy/5794835_d15905c7c8_n.jpg
D:/daisy/5794839_200acd910c_n.jpg
--------------------------------------
The end.
Reference
1.Marc Gregoire, Nicholas A. Solter, Scott J. Kleper. C++ Advanced programming ( The first 2 edition ). tsinghua university press ,2012
边栏推荐
- Class structure in C language - dot
- Copy 10 for one article! The top conference papers published in South Korea were exposed to be plagiarized, and the first author was "original sin"?
- Why do more and more users give up swagger and choose apifox
- 5A synchronous rectifier chip 20V to 12v2a/5v4.5a high current 24W high power synchronous rectifier chip high current step-down IC fs2462
- How to solve the problem that the computer wireless network does not display the network list
- Setup and upload of arduino-esp32 flash file plug-in program
- Shareit a une force exceptionnelle et se connecte au top 7 de la liste mondiale des forces IAP
- MySQL multi table joint query
- The counter attack story of Fu Jie, a young secondary school student: I spent 20 years from the second undergraduate to the ICLR outstanding Thesis Award
- Customize MySQL connection pool
猜你喜欢
初识exception
Flutter series part: detailed explanation of GridView layout commonly used in flutter
[today in history] June 28: musk was born; Microsoft launches office 365; The inventor of Chua's circuit was born
Mysql database literacy, do you really know what a database is
新品体验:阿里云新一代本地SSD实例i4开放公测
Unit test ci/cd
1015. picking flowers
Mobile web training day-2
Centos6.5 php+mysql MySQL library not found
Google Earth Engine(GEE)——联合国粮农组织全球有机土壤面积(1992-2018年度)
随机推荐
Vscode shortcut key
抢做意大利岛主?刘强东两月套现66亿 疑一次性5.6亿“紧急转账”急购欧洲海上皇宫
Electronic components distribution 1billion Club [easy to understand]
全志V853芯片 如何在Tina V85x平台切换sensor?
弹性盒子自动换行小Demo
一文抄 10 篇!韩国发表的顶级会议论文被曝抄袭,第一作者是“原罪”?
Visual design tutorial of word cloud
Professional English calendar questions
In the past four years, the number of users exceeded 100 million, and sun Ge led the wave field to a new high
哈希竞猜游戏系统开发技术成熟案例及源码
Mobile web training -flex layout test question 1
决策树预测红酒品质
The press conference of Tencent cloud Database & CSDN engineer's ability lightweight certification is coming
初识exception
Copy 10 for one article! The top conference papers published in South Korea were exposed to be plagiarized, and the first author was "original sin"?
移动Web实训DAY-1
VSCode 快捷键
codeblocks mingw安装配置问题
Customize MySQL connection pool
求职简历的书写技巧