您的位置:首页 > 新闻 > 资讯 > 门户网站是用户上网的第一入口_企业怎么做网站做网站的公司_快速排名优化推广价格_aso优化服务站

门户网站是用户上网的第一入口_企业怎么做网站做网站的公司_快速排名优化推广价格_aso优化服务站

2025/1/11 5:37:04 来源:https://blog.csdn.net/klausur31/article/details/145063725  浏览:    关键词:门户网站是用户上网的第一入口_企业怎么做网站做网站的公司_快速排名优化推广价格_aso优化服务站
门户网站是用户上网的第一入口_企业怎么做网站做网站的公司_快速排名优化推广价格_aso优化服务站

1.C语言的错误处理方式

1.1直接终止程序

利用assert和exit都是直接终止程序。

1.2返回错误码

例如C语言程序的很对接口函数都会将错误信息存储在errno中表示错误。当我们自己设计函数时,函数返回值和返回错误码容易混淆,且如果函数调用栈较深时,一层层返回很难处理。

2.C++异常处理

2.1异常定义

异常是面向对象语言处理错误的一种方式,它主要由三个关键部分组成:throw 抛出异常

try 中放置可能会抛异常的代码,catch 用于捕获异常。

如下代码,是我们捕获的C++中的异常。

vector<int> v{ 1,2,5,6,4,5 };
try
{cout << v.at(10)<< endl;
}
catch (const exception& e)
{cout << e.what() << endl; //invalid vector subscript
}
return 0;

我们还可以自己设计自己的函数,并抛出异常。 

int divi(const int& x1, const int& x2) {if (x2 == 0) {throw string("除数为零");}return x1 / x2;
}int main() {try {cout << divi(10, 0) << endl;}catch (const string& e) {cout << e << endl;}

理论上讲,throw抛出的异常我们可以任意设计但是在公司设计时,我们抛出的常常是派生类,然后用基类来捕获。 这样设计可以更加的规矩,有序。

class Exception {
public:Exception(const int& id, const string& errmsg):_id(id),_errmsg(errmsg){}virtual string what()const = 0;    //纯虚类
protected:int _id;string _errmsg;
};class SqlException :public Exception {
public:SqlException(const int& id,const string& errmsg):Exception(id,errmsg){}virtual string what() const{return "SQL :" + _errmsg;}
};class CacheException :public Exception {
public:CacheException(const int& id, const string& errmsg):Exception(id, errmsg){}virtual string what() const{return "Cache:" + _errmsg;}
};
void func1()
{if (rand() % 9 == 0) {throw SqlException(100, "权限不足");}
}int main() {srand(time(NULL));int n = 10;while (n){try {func1();}catch (const Exception& e) {  //利用了多态cout << e.what() << endl;}catch(...){cout << "处理成功" <<endl;}n--;}
}

2.2异常的安全问题

void func2() {char* arr = new char;if (rand() % 9 == 0)throw string("抛出异常");delete arr;
}

例如当我们调用func2函数时,有可能会抛出异常,那么arr就不能被delete掉,造成内存泄漏。我们可以利用异常重抛出,来解决内存泄漏问题。

void func2() {char* arr = new char;try{if (rand() % 9 == 0)throw string("抛出异常");}catch (...) {    //如果有异常,则捕获全部异常,这里捕获后用来delete掉arr//然后重新抛出异常delete arr;throw;}delete arr;
}

我们还可以利用RAII来解决此类问题。

我们在构造函数和析构函数时最好不要抛出异常,不然容易导致资源泄漏和对象初始化不完全。

2.3 c++中的异常库

c++中的异常库都从exception基类派生出来的,因此我们捕获c++库函数的异常时,只需要捕获基类的exception,利用多态的原理,访问what函数即可得到错误信息。 

2.4异常抛出和使用的原则

1. 异常是通过 抛出对象而引发 的,该 对象的类型 决定了应该激活哪个 catch 的处理代码。
2. 选中的处理代码 是调用链中 与该对象类型匹配且离抛出异常位置最近 的那一个。
3. 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象
所以会生成一个拷贝对象,这个拷贝的临时对象会在被 catch 以后销毁。(这里的处理类似
于函数的传值返回)
4. catch(...) 可以捕获任意类型的异常,问题是不知道异常错误是什么。
5. 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配, 可以抛出的派生类对象,利用基类捕获,再利用多态的原理。

2.5异常在函数栈上的捕获

1. 首先 检查 throw 本身是否在 try 块内部,如果是再查找匹配的 catch 语句 。如果有匹配的,则
调到 catch 的地方进行处理。
2. 没有匹配的 catch 则退出当前函数栈,继续在调用函数的栈中进行查找匹配的 catch
3. 如果到达 main 函数的栈,依旧没有匹配的,则终止程序 。上述这个沿着调用链查找匹配的
catch 子句的过程称为 栈展开 。所以实际中我们最后都要加一个 catch(...) 捕获任意类型的异
常,否则当有异常没捕获,程序就会直接终止。
4. 找到匹配的 catch 子句并处理以后,会继续沿着 catch 子句后面继续执行。

2.6异常的优缺点

优点①抛出的类定义好后可以清晰的获得错误的信息

②多层调用时,里面的抛出异常后,不需要层层传递,直接在需要的地方catch即可。

③能很好解决c语言中没返回值不能返回错误码的问题,以及返回的错误码和返回值混淆的问题。

④很多第三方库都包含异常。

缺点①导致程序执行顺序混乱

②C++没有垃圾回收机制,容易出现死锁和内存泄漏问题,需要RAII解决

③使用不规范问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com