C++学习七:异常处理、转换函数、智能指针
一.异常处理
1.核心思想
? ? 让函数的设计者去检查错误,检查到错误时抛出异常,而函数的使用者捕获异常并处理异常
2.C++的异常处理机制有3部分组成:
? ? try(检查错误) -> throw(抛出异常) -> catch(捕获异常)
3.异常语法形式
? ? try{
? ? ? ? //检查错误
? ? ? ? if(错误)
? ? ? ? ? ? throw 异常
? ? }catch(异常1)
? ? {
? ? ? ? 处理异常
? ? }catch(异常2)
? ? {
? ? ? ? 处理异常
? ? }
? ? eg:? ? ? ?
int divior(int x, int y)
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y; //正确:返回结果
? ? ? ? ? ? else //y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? int m = 1;
? ? ? ? ? ? int n = 0;
? ? ? ? ? ? try{ //检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ?
? ? ? ? ? ? return 0;
? ? ? ? }
4.自定义异常
? ? eg1:由标准异常类派生? ? ? ?
class myexception : public exception{
? ? ? ? public:
? ? ? ? ? ? myexception(const char *str) noexcept : ptr(str) ?//指定异常不再抛异常
? ? ? ? ? ? {
? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? ~myexception() noexcept //自动为序虚
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? const char* what() const noexcept //重写基类的虚函数
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return ptr;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? const char *ptr;
? ? ? ? };
? ? ? ? int divior(int x, int y)
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y;//正确:返回结果
? ? ? ? ? ? else if(0 == x)
? ? ? ? ? ? ? ? throw myexception("x == 0");//抛出自定义异常
? ? ? ? ? ? else//y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出标准异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? int m = 0;
? ? ? ? ? ? int n = 1;
? ? ? ? ? ? try
{ //检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? }
catch(const myexception &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ? ? ?
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ?
? ? eg2:不由标准异常类派生,自定义异常类? ? ?
? class myexception{
? ? ? ? public:
? ? ? ? ? ? myexception(const char *str) noexcept: ptr(str) ?//指定异常不再抛异常
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~myexception() noexcept //自动为序虚
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? virtual const char* what() const noexcept //重写基类的虚函数
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return this->ptr;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? const char *ptr;
? ? ? ? };
? ? ? ? int divior(int x, int y)
? ? ? ? throw(invalid_argument)//指定函数可以抛出invalid_argument类型的异常
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y;//正确:返回结果
? ? ? ? ? ? else if(0 == x)
? ? ? ? ? ? {
? ? ? ? ? ? #if 0
? ? ? ? ? ? ? ? throw myexception("x == 0");//抛出自定义异常
? ? ? ? ? ? #else
? ? ? ? ? ? ? ? myexception tmp("x == 0");
? ? ? ? ? ? ? ? throw tmp;
? ? ? ? ? ? #endif
}
? ? ? ? ? ? else//y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出标准异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? int m = 0;
? ? ? ? ? ? int n = 1;
? ? ? ? ? ? try
{//检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? }
catch(const myexception &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ? ? ?
? ? ? ? ? ? return 0;
? ? ? ? }
二.转换函数
1.目的
? ? 实现基本类型和自定义类型之间的转换;
2.语法形式
? ? operator 新类型() const
? ? {
? ? ? ? //转换语句
? ? }
? ? eg:
? ? ? ? operator int() const //自定义类型转int
? ? ? ? {
? ? ? ? }
? ? 注意:
? ? ? ? 转换函数只能是成员函数,无返回值,空参数。
? ? ? ? 不能定义到void的转换,也不允许转换成数组或者函数类型。
? ? ? ? 转换常定义为const形式,原因是它并不改变数据成员的值。
3.explicit关键字
? ? 阻止隐式类型转换;
? ? eg:? ? ? ?
class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val) //explict:阻止隐式类型转换
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? public:
? ? ? ? ? ? void setval(int val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? }
? ? ? ? ? ? int getval() const
? ? ? ? ? ? {
? ? ? ? ?? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? Demo obj(666);
? ? ? ? obj = 123;//Demo tmp(123); obj = tmp; ? 隐式类型转换: int -> Demo
? ? ? ? cout << obj.getval() << endl;
? ? ? ? return 0;
? ? }
4.C++标准转换函数
? ? 编译时转换:reinterpret_cast、const_cast、static_cast
? ? 运行时候转换:dynamic_cast
? ?
? ? 1)reinterpret_cast
? ? ? ? 语法:reinterpret_cast<new type>(expression)
? ? ? ? 功能:将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型
? ? ? ? eg:
? ? ? ? ? ? char *p;
? ? ? ? ? ? int *q;
? ? ? ? ? ? q = reinterpret_cast<int *> (p);//char * -> int *
? ? 2)const_cast
? ? ? ? 语法:const_cast< ?new type>( expression)
? ? ? ? 功能:const指针与普通指针间的相互转换,注意:不能将非常量指针变量转换为普通变量
? ? ? ? eg:
? ? ? ? ? ? const int *p;
? ? ? ? ? ? int *q;
? ? ? ? ? ? q = const_cast<int *>(p);//const int * -> int *
? ? ? ? ? ?
? ? 3)static_cast(普通类类型转换)
? ? ? ? 语法:static_cast<new type>(expression)
? ? ? ? 功能:主要用于基本类型间的相互转换,和具有继承关系间的类型转换
? ? ? ? eg:? ? ? ? ? ?
class Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };
? ? ? ? class Inherit : public Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Inherit()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Inherit()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? Base *p;
? ? ? ? ? ? Inherit *q;
? ? ? ? ? ? //p = q;//Inherit * -> Base *
? ? ? ? ? ? q = static_cast<Inherit *> (p); //Base * -> Inherit *
? ? ? ? ? ? return 0;
? ? ? ? }
? ? 4)dynamic_cast(有虚函数的类型转换)
? ? ? ? 语法:dynamic_cast<newtype>(expression)
? ? ? ? 功能:只有类中含有虚函数才能用dynamic_cast;仅能在继承类对象间转换
? ? ? ? 注意:dynamic_cast具有类型检查的功能,比static_cast更安全
? ? ? ? eg:? ? ? ? ? ?
class Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };
? ? ? ? ? ? class Inherit : public Base{
? ? ? ? ? ? ? ? public:
? ? ? ? ? ? ? ? ? ? Inherit()
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ~Inherit()
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ?cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? int main()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Base *p;
? ? ? ? ? ? ? ? Inherit *q;
? ? ? ? ? ? ? ? //p = q;//Inherit * -> Base *
? ? ? ? ? ? ? ? q = dynamic_cast<Inherit *> (p); //Base * -> Inherit *
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? }
5.自定义转换函数
? ? eg:? ? ?
? class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val) : val(val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? public:
? ? ? ? ? ? operator int() const //转换函数:Demo -> int
{
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? Demo obj(666);
? ? ? ? int i;
? ? ? ? i = obj; //Demo -> int
? ? ? ? cout << "i=" << i << endl;
? ? ? ? return 0;
? ? }
三.智能指针
本质:类模板,模板中重载了->和*运算符。
1.shared_ptr指针
?
template <class T>
? ? class myshared_ptr{
? ? public:
? ? ? ? myshared_ptr(T *p) : ptr(p)
? ? ? ? {
? ? ? ? ? ? count ++;
? ? ? ? }
? ? ? ? myshared_ptr(const myshared_ptr<T> &obj)
? ? ? ? {
? ? ? ? ? ? cout++;
? ? ? ? }
? ? ? ? ~myshared_ptr()
? ? ? ? {
? ? ? ? ? ? count--;
? ? ? ? ? ? if(0 == count)
? ? ? ? ? ? ? ? delete ptr;
? ? ? ? }
? ? public:
? ? ? ? operator ->()//重载->运算符
{
? ? ? ? }
? ? ? ? operator *() //重载*运算符
? ? ? ? { }
? ? private:
? ? ? ? T *ptr;
? ? };
? ?
2.unique_ptr指针(独享指针)
? ? eg:? ? ? ?
class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val=0) :val(val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? public:
? ? ? ? ? ? void setval(int val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? }
? ? ? ? ? ? int getval() const
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? unique_ptr<Demo> p(new Demo);//构造对象p
? ? ? ? //unique_ptr<Demo> pp = p;//禁止拷贝构造
? ? ? ? p->setval(666);//等价:(*p).setval(666);
? ? ? ? cout << p->getval() << endl;
? ? ? ? return 0;
? ? }
3.weak_ptr(弱指针)
? ? 通常配合共享指针进行操作;
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!