C++成员初始化列表

本文详细介绍了C++中成员初始化列表的作用和应用场景,包括初始化非静态const成员变量、成员引用、基类成员以及其他类的对象成员。成员初始化列表在构造函数中起到关键作用,它决定了如何在构造过程的初始化阶段对这些成员进行初始化,从而提高效率并避免错误。总结指出,成员初始化列表主要在初始化阶段工作,并且在该阶段结束后,才执行构造函数体。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++成员初始化列表

首先明确,成员初始化列表只能用于构造函数

1.使用成员初始化列表的情况

I>初始化非静态const成员变量

class A{
private:
    const int a;
public:
    A(); 
};

怎么编写构造函数来初始化成员变量a呢?
可能会想到这样

A::A(){
    a = value;
}

其实这是一个赋值过程,在执赋值之前,初始化已经完成了,const变量是不可以被赋值的,只能在初始化的时候给一个值

所以这里用到成员初始化列表,成员初始化列表指出了怎样初始化

A::A() : a(value){}

II>初始化成员引用

class A{
private:
    int &a;
public:
    A();
}

与非静态const成员一样,左引用绑定一个左值只能在初始化阶段完成所以这里用到成员初始化列表,成员初始化列表指出了怎样初始化

A::A() : a(left_value){}

III>初始化基类成员

基类:

class ClassBase{
private:
    int a;
public:
    ClassBase();
    ClassBase(int a);
}

派生类:

class ClassDerived:public ClassBase{
private:
    ...派生类扩展的成员
public:
    ClassDerived(int x);
}

public继承会继承基类的私有成员,但是只能由基类的接口访问,所以对于派生类的构造函数,不能简单的使用赋值进行初始化基类成员

因此,在执行派生类构造函数之前,要先执行基类的构造函数

同样,可以使用成员初始化列表,表示基类怎样初始化 ,也就是说,显式的告诉编译器调用哪一个构造函数初始化基类成员

调用基类的有参构造

ClassDerived::ClassDerived(int x):ClassBase(x){
    ...
}

调用基类的无参构造

ClassDerived::ClassDerived() : ClassBase(){
    ...
}

ClassDerived::ClassDerived(){
    ...
}

成员初始化列表不表示构造函数调用过程,表示了调用哪一个,如果不加成员初始化列表,则表示基类调用默认构造函数(无参的构造函数)

IV>初始化其他类的对象成员

class A {
public:
    A();
    A(int a);
    const A &operator=(const A &obj);
};

A::A() {
    cout << "A()" << endl;
}
A::A(int a) {
    cout << "A(int)" << endl;
}
const A &A::operator=(const A &obj) {
    cout << "A::operator=(const A &)" << endl;
    return obj;
}


class B {
private:
    A objA1;
    A objA2;
public:
    B();
};

可以怎样初始化B的对象中的objA1和objA2呢?

第一种,赋值

B::B() {
    objA1 = A();
    objA2 = A(3);
}

int main() {

    B objb;
    return 0;
}

输出:

A()                 
A()     
A()                     << 生成临时对象调用无参构造
A::operator=(const A &) << objA1.operator=(上面的临时对象)
A(int)                  << 生成临时对象调用有参构造
A::operator=(const A &) << objA2.operator=(上面的临时对象)

通过分分析,可以发现,在执行函数体之前,已经调用过两次默认的构造函数,可以使用成员初始化列表,在初始化阶段(构造函数体执行之前)表示调用哪一个构造函数

B::B() : objA1(), objA2(3){}

输出:

A()
A(int)

如果调用默认的无参构造,可以省略

比较发现,使用成员初始化列表的效率会比赋值高得多

2.总结一下

I>成员初始化列表作用在初始化阶段

对于基本类型来说,初始化和赋值没什么区别。

对于类对象:初始化列表表示了调用哪一个构造函数,不写初始化列表表示调用默认。

II>初始化阶段完成后,执行构造函数体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值