zoukankan      html  css  js  c++  java
  • 为什么要是用初始化成员列表

    在初始化类的成员的时候,我们经常会有两种选择,其一是类构造函数的成员初始化列表,其二是构造函数的函数体。那么这两者的区别又是什么,成员初始化列表的具体行为到底是什么呢?

    类对象的构造顺序是这样的:

    1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员;

    2.进入构造函数后在构造函数中执行一般赋值与计算。

    性能上的区别

    看下面一段代码:

    inline String::String()
    {
        cout<<"String的默认构造函数"<<endl;
    ...
    }
     
    inline String::String(const char *s)
    {
        printf("String(const char *s)的构造函数,s=%s
    ",s);
    ...
    }
     
    class testclass{
    public:
        testclass();
        testclass(char *a,int b);
    private:
        String _name;
        char _b;
    };
     
    testclass::testclass()
    {
        printf("默认构造函数
    ");
    }
     
    testclass::testclass(char *a, int b)
    {
      cout<<"testclass的构造函数"<<endl;
        _name=a;
        _b=b;
    }
    testclass("abc",12); 
    //结果为: 
    //String的默认构造函数 
    //testclass的构造函数 
    //String(const char *s)的构造函数,s=abc

      

    这种初始化方式是在构造函数体内给成员变量赋值。有日志可以看出初始化过程中发生了如下几件事情:

    1、首先调用String的default构造函数给_name赋初值

    2、然后进入testclass的构造函数体内

    3、立刻再对_name赋予新值

    再看下一段代码,用初始化成员列表的形式进行初始化:

    testclass::testclass(char *a, int b):_name(a),_b(b)
    {
     cout<<"testclass的构造函数"<<endl;
    }
    //结果为: 
    //String(const char *s)的构造函数,s=abc 
    //testclass的构造函数
    

      

    可见第一种方式(即在构造函数内部赋值)虽然效果一样,但是多调用了一次default构造函数,有点浪费了,特别是当一个类中成员很多,且多为自定义的类类型时,资源就更浪费了。使用初始化成员列表的方式避免了这一浪费,直接调用string copy构造函数(不一定是copy 构造函数),更加高效。还有其他原因,待研究。。。 

     功能上的区别

    除了性能上面的差别,有几种情况下必须使用初始化成员列表而非函数体内赋值来初始化变量:

    1、初始化引用类型的成员变量;

    2、初始化const类型的成员变量;

    3、当在初始化一个子类的时候,其父类没有默认构造函数,即不带参数的构造函数,只有显示含有参数的构造函数;

    4、类含有类成员变量(包括继承的和本身的)

    对于1、2两点比较好理解,因为const、引用类型不接受定义之后的赋值。

    对于3的话,我们调用子类的构造函数之前,会先调用父类的构造函数。如果父类只有带参数的构造函数,那就会调用带参数的构造函数,这时候就必须使用初始化成员列表传入参数给父类的带参数的构造函数。否则无法完成父类的初始化,编译会报错。

    对于4,如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。

  • 相关阅读:
    Node Sass version 5.0.0 is incompatible with^4.0.0
    解决vue-cli引入sass,报错:this.getResolve is not a function问题
    解决nuxt官方脚手架的一些坑:1、支持es6+语法 2、样式支持sass
    针对【create-nuxt-app新版本v3.2.0】构建项目时没有server配置以及运行后弹出收集匿名数据选项等问题的解决方法
    create-nuxt-app创建出来的目录没有server文件夹
    Redis安装(Windows环境下Redis安装)
    koa2中间件,路由,cookies
    用同步的写法来执行异步操作, async, awiat
    koa2 安装与启动
    练习:自己写一个容器ArrayList集合 一一数组综合练习
  • 原文地址:https://www.cnblogs.com/howo/p/7476575.html
Copyright © 2011-2022 走看看