C++ 类成员变量初始化

引言

在C++中,类的成员变量初始化是保证对象正确构建的关键。本文将深入探讨C++类成员变量初始化,重点关注初始化列表的作用、使用场景以及与构造函数体赋值的区别。

为什么需要初始化列表?

初始化列表是C++构造函数中的一种语法,用于在构造函数开始执行之前初始化成员变量。它通常出现在构造函数的参数列表之后,冒号之后。为什么需要初始化列表呢?

  • 引用成员: 引用必须在声明时初始化,且不能被重新赋值。因此,引用类型的成员变量只能在初始化列表中初始化。
  • const成员: const成员变量的值在编译期就已经确定,因此也必须在初始化列表中初始化。
  • 自定义类型成员没有默认构造函数: 如果自定义类型的成员变量没有默认构造函数,则必须在初始化列表中提供初始化参数,以调用该成员类型的构造函数。
  • 效率: 在初始化列表中初始化成员变量,通常比在构造函数体中赋值的效率更高,因为初始化列表中的初始化操作是在构造函数体执行之前进行的,避免了不必要的默认构造和赋值操作。

初始化列表的使用

class Data{
public:
    Data(int year = 0, int month = 1, int day = 1)
        : _year(year), _month(month), _day(day) {} // 初始化列表
private:
    int _year;
    int _month;
    int _day;
};

在上面的用法中,我们使用初始化列表初始化_year,_month和_day。当然这个通过普通赋值也可以实现,接下来让我们看不可以通过普通赋值实现的。例如,常量成员、引用成员和没有默认构造函数的成员都必须使用初始化列表。

示例:常量成员变量

class Data {
public:
    Data(int year = 0, int month = 1, int day = 1)
        : _year(year), _month(month), _day(day), _id(100) {} // 初始化列表初始化 const 成员
private:
    const int _id;  // 常量成员必须通过初始化列表进行初始化
    int _year;
    int _month;
    int _day;
};

在这个例子中,_id 是一个常量成员。由于常量成员在对象构造后不能被修改,必须通过初始化列表赋值。在构造函数体内进行赋值将会导致编译错误。

示例:引用成员变量

class Data {
public:
    Data(int& ref, int year = 0, int month = 1, int day = 1)
        : _ref(ref), _year(year), _month(month), _day(day) {}  // 初始化列表初始化引用成员
private:
    int& _ref;  // 引用成员必须通过初始化列表进行初始化
    int _year;
    int _month;
    int _day;
};

在这个例子中,_ref 是一个引用。引用必须在对象构造时进行初始化,不能像普通变量一样通过赋值改变。

示例:没有默认构造函数的成员变量

class AnotherClass {
public:
    AnotherClass(int val) : _val(val) {}
private:
    int _val;
};

class Data {
public:
    Data(int year = 0, int month = 1, int day = 1)
        : _year(year), _month(month), _day(day), _other(year) {}  // 初始化列表初始化没有默认构造函数的成员
private:
    int _year;
    int _month;
    int _day;
    AnotherClass _other;  // AnotherClass 没有默认构造函数,因此必须使用初始化列表
};

这里的 AnotherClass 没有默认构造函数,因此成员 _other 必须在初始化列表中提供参数进行初始化。如果试图在构造函数体内进行赋值,将会导致编译错误。

总结来说,初始化列表在以下情况下是必须的:

  1. 常量成员 (const)
  2. 引用成员 (&)
  3. 没有默认构造函数的类成员

初始化列表与构造函数体赋值的区别

  • 执行顺序: 初始化列表中的初始化操作是在构造函数体执行之前进行的。
  • 效率: 初始化列表通常比构造函数体赋值的效率更高。
  • 引用和const成员: 引用和const成员只能在初始化列表中初始化。

初始化顺序

  • 初始化顺序与初始化列表无关,与成员变量在类中的声明顺序有关。
  • 成员变量的声明顺序决定了初始化的顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小毓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值