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(弱指针)

    通常配合共享指针进行操作;

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值