zoukankan      html  css  js  c++  java
  • C++ 构造函数_初始化列表

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:

    class Student 
    {
    public:
    
        //构造函数初始化列表
        Student():m_strName("cjj"),m_iAge(22){}
    
        //构造函数内部赋值
        Student()
        {
            m_strName = "cjj";
            m_iAge = 22;
        }
    private:
        string m_strName;
        int m_iAge;
    };

    上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。

    初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:

    • 1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。
    • 2.const 成员引用类型的成员。因为 const 对象或引用类型只能初始化,不能对他们赋值。
    class Student 
    {
    public:
    
        //构造函数初始化列表可以对const类型的常量进行初始化
        Student():m_dPi(3.14){}
    
        //普通赋值,因为 m_dPi 是const类型的,相当于一个常量,所以赋值不对
        //Student(){m_dPi = 3.14;}
    
    private:
        const double m_dPi;
    };

    初始化数据成员与对数据成员赋值的含义是什么?有什么区别?

    首先把数据成员按类型分类并分情况说明:

    • 1.内置数据类型,复合类型(指针,引用)- 在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
    • 2.用户定义类型(类类型)- 结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)

    初始化列表特性

    1、初始化列表先于构造函数执行

    2、初始化列表只能用于构造函数

    3、初始化列表可以通知初始化多个数据成员

    代码示例

    demo.cpp

    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "Teacher.h"
    using namespace std;
    
    /*************************************************************************
    Teacher类
        自定义有参构造函数
        使用初始化列表初始化数据
    
    数据成员:
        姓名
        年龄
    
    成员函数:
        数据成员的封装函数
    
    拓展:
        定义可以带最多学生的个数,此为常量
    
    *************************************************************************/
    
    int main(void)
    {
        Teacher t1;        // 不给初始化列表产地参数,构造函数会使用默认的参数
        cout<<t1.getName()<<" "<<t1.getAge()<<endl;
    
        Teacher t2("Tom",33); // 给初始化列表传要初始化的参数,不对const进行初始化
        cout<<t2.getName()<<" "<<t2.getAge()<<" "<<t2.getMax()<<endl;
    
        Teacher t3("Jess",44,150);  // 对const进行初始化
        cout<<t3.getName()<<" "<<t3.getAge()<<" "<<t3.getMax()<<endl;
    
        system("pause");
        return 0;
    }

    Teacher.h

    #include<string>
    using namespace std;
    
    class Teacher
    {
    public:
        // 声明构造函数,参数给定默认值
        Teacher(string name = "cjj",int age = 22, int m = 100);
    
        // 声明成员函数,把所有的成员函数都罗列出来
        void setName(string _name);
        string getName();void setAge(int _age);
        int getAge();int getMax();
    
    private:
        string m_strName;int m_iAge;    
        const int m_iMax; // 定义可以带最多学生的个数,此为常量
    };

    Teacher.cpp

    #include"Teacher.h"
    #include<iostream>
    using namespace std;
    
    // 定义构造函数,使用初始化列表,初始化构造函数的参数
    //m_iMax(m)为常量,只能使用初始化列表进行初始化
    Teacher::Teacher(string name,int age,int m):m_strName(name),m_iAge(age),m_iMax(m)
    {
        cout << "Teacher(string name,int age)" << endl;
    }
    
    // 类外定义,写出成员函数的函数体
    void Teacher::setName(string _name)
    {
        m_strName = _name;
    }
    string Teacher::getName()
    {
        return m_strName;
    }
    
    void Teacher::setAge(int _age)
    {
        m_iAge = _age;
    }
    int Teacher::getAge()
    {
        return m_iAge;
    }
    
    int Teacher::getMax() // 返回m_iMax值
    {
        return m_iMax;
    }

    运行结果:

  • 相关阅读:
    Oracle 按一行里某个字段里的值分割成多行进行展示
    Property or method "openPageOffice" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by
    SpringBoot 项目启动 Failed to convert value of type 'java.lang.String' to required type 'cn.com.goldenwater.dcproj.dao.TacPageOfficePblmListDao';
    Maven 设置阿里镜像
    JS 日期格式化,留作参考
    JS 过滤数组里对象的某个属性
    原生JS实现简单富文本编辑器2
    Chrome控制台使用详解
    android权限(permission)大全
    不借助第三方网站四步实现手机网站转安卓APP
  • 原文地址:https://www.cnblogs.com/chuijingjing/p/9250910.html
Copyright © 2011-2022 走看看