当前位置:网站首页>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
边栏推荐
- 电子元器件分销10亿俱乐部[通俗易懂]
- 我呕血收集融合了来自各路经典shell书籍的脚本教学,作为小白的你快点来吧
- thinkphp6 多级控制器目录访问解决方法
- Hubble database x a joint-stock commercial bank: upgrade the number management system of Guanzi, so that every RMB has an "ID card"
- New product experience: Alibaba cloud's new generation of local SSD instance I4 open beta
- Embedded development: seven techniques for estimating battery life
- Mobile web training day-1
- redis和mysql数据不一致问题如何解决?
- Vscode shortcut key
- 无心剑英译朱熹《观书有感二首·其一》
猜你喜欢

中国数据库技术大会(DTCC)特邀科蓝SUNDB数据库专家精彩分享

FH511+TP4333组成一个户外移动电源照明野营灯方案。

Realization of a springboard machine

数启扬帆,智聚人才 | 腾讯云数据库 & CSDN 工程师能力轻量认证发布会重磅来袭!...

全志V853芯片 如何在Tina V85x平台切换sensor?

Successful cases of rights protection of open source projects: successful rights protection of SPuG open source operation and maintenance platform

移动Web实训-flex布局测试题1

scratch旅行相册 电子学会图形化编程scratch等级考试一级真题和答案解析2022年6月

Writing skills of resume

China Database Technology Conference (DTCC) specially invited experts from Kelan sundb database to share
随机推荐
求职简历的书写技巧
List集合转数组
PHP gets the number of digits and replaces it with the specified mantissa
设计人工智能产品:技术可能性、用户合意性、商业可行性
RK3399平台开发系列讲解(使用篇)Pinctrl子系统的介绍 - 视频介绍
Successful cases of rights protection of open source projects: successful rights protection of SPuG open source operation and maintenance platform
G1 important configuration parameters and their default values in the garbage collector
其他国产手机未能填补华为的空缺,苹果在高端手机市场已无对手
The difference between align items and align content
Centos6.5 php+mysql MySQL library not found
Centos7:切换mysql用户并登录mysql
Tiantian mathematics serial 53: February 22
中国广电5G套餐来了,比三大运营商低,却没预期那么低
Hubble数据库x某股份制商业银行:冠字号码管理系统升级,让每一张人民币都有 “身份证”
Mobile web training -flex layout test question 1
词云的可视化设计教程
Hang Seng Electronics: lightdb, a financial distributed database, has passed a number of evaluations by China Academy of communications technology
yii2编写swoole的websocket服务
5A同步整流芯片 20V转12V2A/5V4.5A大电流 24W大功率同步整流芯片 大电流降压IC FS2462
How about stock online account opening and account opening process? Is it safe to open a mobile account?