c++成员初值列/成员初始化列表

本文探讨了C++中对象成员变量的初始化与赋值的区别,并强调了使用成员初值列进行构造函数初始化的重要性。

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

1.应用背景:

如果我们只是简单的int x;去定义一个x变量,此时的x未被初始化,那么当我们读取这个未初始化的值时会导致不明确的行为发生。因此最佳的处理办法就是:永远在使用对象之前先将它初始化。对于无任何成员的内置类型,我们通常必须手工完成此事。如:int x = 0;

但对于内置类型以外的任何其他东西,初始化责任就落在构造函数的身上,其规则也很简单:确保每一个构造函数都将对象的每一个成员初始化

2.从区分“赋值”与“初始化”中探究“成员初值列”:

首先需要明白赋值(assignment)和初始化(initialization)的概念:

class test{
public:
    test(const std::string& name, const int& num);
private:
    std::string m_name;
    int m_num;
    int sp_num;
};
test::test(const std::string& name, const int& num){
    m_name = name;  //此方式为赋值,而非初始化
    m_num = num;
    sp_num = 0;
}

以上的例子为赋值而非初始化,它会使test类带有你期望的值,但并非最佳做法c++规定,对象的成员变量的初始化动作要发生在进入构造函数本体之前。因此,初始化的发生时间更早,发生于这些成员的default构造函数被自动调用之时(比进入test构造函数本题的时间更早)。(但对于sp_num变量来说,却不适用,因为sp_num为内置类型,不保证一定在你所看到的那个赋值动作的时间点之前获得初值)

test::test(const std::string& name, const int& num)
    :m_name(name),//此刻均为初始化
     m_num(num),
     sp_num(0)
{}

而以上为构造函数的一个较佳写法,使用成员初值列(member initialization list)替换赋值动作。此时的方法于上一个的最终结果相同,但通常效率会更高。因为第一个赋值版本的代码会先调用default构造函数为m_name,m_num, sp_num设初值,然后立即再对它们赋予新值。而第二个成员初值列的方法避免了这一问题,因为初值列中针对各个成员变量而设的实参,被拿去作为各成员变量的构造函数实参。

因此,其高效原理为:比起先调用default构造函数然后再调用copy assignment操作符,单只调用一次copy构造函数是更为高效的。(但对于内置对象sp_num来说,其初始化与赋值的成本相同)

对于无特指参数也可以设定这样的无参数构造函数:

test::test()
    :m_name(),//调用m_name的default构造函数
     m_num(),
     sp_num(0)
{}

提醒:我们需要总是使用成员初值列,且总是在初值列中列出所有成员变量,以免还得记住哪些成员变量可以无需初值。

参考文献

《Effective C++(第三版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值