zoukankan      html  css  js  c++  java
  • C++ Throw exception in contructor 构造函数异常处理

    class ComplexA
    {
    public:
    ComplexA(int len):_l(len), _p(new char[_l]){cout<<"ComplexA::ComplexA"<<endl;}
    ~ComplexA(){cout<<"ComplexA::~ComplexA"<<endl; if (_p != nullptr) delete _p;}
    private:
    int _l;
    char * _p;
    };
    class ComplexB
    {
    public:
    ComplexB(int len):_l(len), _p(new char[_l]){cout<<"ComplexB::ComplexB"<<endl;}
    ~ComplexB(){cout<<"ComplexB::~ComplexB"<<endl; if (_p != nullptr) delete _p;}
    private:
    int _l;
    char * _p;
    };
    class ComplexC
    {
    public:
    ComplexC(int len):_l(len), _p(new char[_l]){cout<<"ComplexC::ComplexC"<<endl;}
    ~ComplexC(){cout<<"ComplexC::~ComplexC"<<endl; if (_p != nullptr) delete _p;}
    private:
    int _l;
    char * _p;
    };
    class Wrapper
    {
    public:
    Wrapper(int lenA, int lenB, int lenC):pA(new ComplexA(lenA)), pB(new ComplexB(lenB)), pC(new ComplexC(lenC)){cout<<"Wrapper::Wrapper"<<endl;}
    ~Wrapper(){cout<<"Wrapper::~Wrapper"<<endl; if (pA) delete pA; if (pB)delete pB; if (pC)delete pC;}
    private:
    ComplexA * pA;
    ComplexB * pB;
    ComplexC * pC;
    };
    如果在ComplexC的构造函数中跑出bad_alloc异常,将会发现之前分配的ComplexA与ComplexB将不会给释放。
    但是如果将Wrapper修改成如下,不是包含复杂对象的指针而是他的实体变量,则会逆序释放部分构造成功的复杂对象:
    class Wrapper2
    {
        public:
            Wrapper2(int _a, int _b, int _c):
                a(_a), b(_b), c(_c)
            {
    
            }
        private:
            ComplexA a;
            ComplexB b;
            ComplexC c;
    };
    输出结果为:

    ComplexA::ComplexA
    ComplexB::ComplexB
    ComplexC::ComplexC
    ComplexB::~ComplexB
    ComplexA::~ComplexA
    Catch bad_alloc

    构造函数中不管是在initialize list中分配,还是构造函数体中,还是会有如下结论:

    构造函数中抛出异常时概括性总结
    (1) C++中通知对象构造失败的唯一方法那就是在构造函数中抛出异常;
    (2) 构造函数中抛出异常将导致对象的析构函数不被执行; 所以如果子对象是指针的形式将会不会释放,因为释放是在母体的析构函数中
    (3) 当对象发生部分构造时,已经构造完毕的子对象将会逆序地被析构;
    (4) 其是还是那句话, “C++的异常处理不会破坏任何一条面向对象的特性!”。

    那么通过上面两个wrapper,是否意味复杂子对象不能用指针来存储呢,否则将会导致部分构造子对象无法释放,不过C++11出来了,智能指针可以拯救你:

    修改wrapper如下:

    class Wrapper3
    {
        public:
            Wrapper3(int la, int lb, int lc):
                pa(make_shared<ComplexA>(la)),
                pb(make_shared<ComplexB>(lb)),
                pc(make_shared<ComplexC>(lc))
            {
    
            }
            ~Wrapper3(){}
        private:
            shared_ptr<ComplexA> pa;
            shared_ptr<ComplexB> pb;
            shared_ptr<ComplexC> pc;
    };

    main函数中

    shared_ptr<Wrapper3> pw = make_shared<Wrapper3>(1,2,3);

    输出结果为:

    ComplexA::ComplexA
    ComplexB::ComplexB
    ComplexC::ComplexC
    ComplexB::~ComplexB
    ComplexA::~ComplexA
    Catch bad_alloc

  • 相关阅读:
    自动配置原理5
    JSR303数据校验4
    mysql 安装(压缩包安装和exe安装)
    jQuery关于复制(复制隐藏文字+显示文字)跳转,Clipboard
    html页面设置一个跟随鼠标移动的DIV(jQuery实现)
    js中将时间(如:2017-10-8 22:44:55)转化为时间搓,时间戳转为标准格式时间
    异常:java.lang.IllegalArgumentException: Control character in cookie value or attribute.
    从数据库导出数据到excel之List<List<Object>>导出
    从数据库导出数据到excel之List<map>导出
    从数据库导出数据到excel之POI操作
  • 原文地址:https://www.cnblogs.com/rogerroddick/p/2966779.html
Copyright © 2011-2022 走看看