构造函数初始化列表【详解】

1.再谈构造函数

1.1构造函数体赋值

在创建对象时候,编译器通过调用构造函数,给对象中的各个成员变量一个合适的初始值

class Date
{
public:
Date(int year, int month, int day)
 {
     _year = year;
     _month = month;
     _day = day;
 }
private:
int _year;
int _month;
int _day;
};

经过构造函数后,对象中已经有了一个初始值,但是这不能成为对象的初始化,构造函数体内的语句最多称为赋初值,而不能称为初始化。因为:初始化只能初始化一次,而构造函数体内可以多次赋值

1.2初始化列表

冒号开头,逗号分隔,每一个成员变量后面跟着一个放在括号中的初始值或者表达式

class Date
{
public:
Date(int year, int month, int day)
     : _year(year)
     , _month(month)
     , _day(day)
 {}
private:
int _year;
int _month;
int _day;
}

注:
1.每个成员变量在初始化列表中只能出现一次(初始化只能一次)
2.类中包含以下成员,必须放在初始化列表位置进行初始化
🔴引用成员变量
🔴const成员变量
::const修饰的变量为常变量,具有常性(不可修改/二次赋值),只能在定义时赋值
🔴自定义类型成员(且该类没有默认构造函数时)

class A
{
public:
    A(int a)
    :_a(a)
    {}
private:
    int _a;
};
class B
{
public:
    B(int a, int ref)
    :_ab(a)
    ,_ref(ref)
    ,_n(10)
    {}
private:
    A _ab; // 没有默认构造函数
    int& _ref; // 引用
    const int _n; // const
};

3.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后
次序无关

请看下题:

class A
{
public:
    A(int a)
       :_a1(a)
       ,_a2(_a1)
   {}
    
    void Print() {
        cout<<_a1<<" "<<_a2<<endl;
   }
private:
    int _a2;
    int _a1;
};
int main() {
    A aa(1);
    aa.Print();
}
A. 输出1  1
B.程序崩溃
C.编译不通过
D.输出1  随机值

按照声明次序初始化,先初始化_a2,_a1此时为随机值,初始化给_a2,所以_a2为随机值,接着初始化_a1,a为1,所以_a1为1,所以选D。

1.3总结

尽量使用初始化列表初始化,因为不管你是否使用初始化列表, 对于自定义类型成员变量,一定会优先使用初始化列表初始化。
初始化的步骤可以尽可能的放在一起,而构造函数体内就可以写其它的需求实现,增加代码的可读性

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值