zoukankan      html  css  js  c++  java
  • c++11 委派构造函数

    委派构造函数可以减少构造函数的书写量:

    class Info {
    public:
     Info() : type(1), name('a') {
      InitRest();
     }
    
     Info(int i) : type(i), name('a') {
      InitRest();
     }
    
     Info(char e) : type(1),, name(e) {
      InitRest();
     }
    
    private:
     void InitRest() { //其他初始化 }
     int type;
     char name;
    };

    每个构造函数都需要初始化列表来初始化成员type和name,且都调用了相同的函数InitRest,存在重复。

    而在C++11中,可以使用委派构造函数来简化代码,如下:

    class Info {
    public:
     Info() { InitRest(); }  //称为目标构造函数(被调用)
     Info(int i) : Info() { type = i; }  //委派构造函数(调用者)
     Info(char e) : Info() { name = e; }
    
    private:
     void InitRest() { // other int }
     int type {1};
     char name {'a'};  
    };

    委派构造函数只能在函数体内为type,name等成员赋值,因为委派构造函数不能有初始化列表。C++中,构造函数不能同时使用委派和初始化列表。

    初始化列表的初始化总是先于构造函数完成,作一下修改:

    class Info {
    public:
     Info() : Info(1, 'a') {}
     Info(int i) : Info(i, 'a') {}
     Info(char e) : Info(1, e) {}
    
    private:
     Info(int i, char e) : type(i), name(e) {} //将初始化动作放在一个通用的构造函数里
     int type;
     char name; 
    };

    在构造函数比较多时,可以有不止一个委派构造函数,目标函数也可以是委派构造函数,可以在委派构造函数中形成链状的委派构造关系。

    class Info {
    public:
     Info() : Info(1) {}
     Info(int i) : Info(i, 'a') {}  //可以委派成链状,但不能形成环。
     Info(char e) : Info(1, e) {}
    
    private:
     Info(int i, char e) : type(i), name(e) {}
     int type;
     char name;
    };

    委派构造函数的应用:

    1.模板:

    #include <list>
    #include <vector>
    #include <deque>
    
    using namespace std;
    
    class TDConstructed {
     template<class T>
     TDConstructed(T first, T last) : l(first, last) {}
    
     list<int> l;
    
    public:
     TDConstructed(vector<short> & v) : TDConstructed(v.begin(), v.end()) {}
     TDConstructed(deque<int> & d) : TDConstructed(d.begin(), d.end()) {}
    }

    以上定义了一个构造函数模板,通过两个委派构造函数的委托,构造函数模板被实例化。

    2. 异常处理:

    #include <iostream>
    using namespace std;
    
    class DCExcept(double d) try : DCExcept(1, d) {
       cout << "Run the body." << endl;   
    } catch(...) {
      cout << "caught exception." << endl;
    }
    
    private:
     DCExcept(int i, double d) {
       cout << "going to throw!" << endl;
       throw 0;
     }
    
     int type;
     double data;
    };
    
    int main() {
     DCExcept a(1.2);
    }

    目标函数中抛出异常,可以在委派构造函数中捕获。

  • 相关阅读:
    Linux关闭防火墙命令
    js改变数组的两个元素的位子,互换、置顶
    vue nexttick的理解和使用场景
    vue mint-ui 框架下拉刷新上拉加载组件的使用
    vue项目中使用了vw适配方案,引入第三方ui框架mint-ui时,适配问题解决
    小程序开发笔记【二】,抽奖结果json数据拼装bug解决
    gulp插件gulp-nunjucks-render的使用及gulp4的简单了解
    小程序开发笔记【一】,查询用户参与活动列表 left join on的用法
    mysql数据插入前判断是否存在
    微信公众号通过图片选取接口上传到阿里oss
  • 原文地址:https://www.cnblogs.com/sssblog/p/10203026.html
Copyright © 2011-2022 走看看