C++成员初始化列表详解

C++成员初始化列表详解

在初始化类的成员的时候,我们经常会有两种选择,其一是类构造函数的成员初始化列表,其二是构造函数的函数体。那么这两者的区别又是什么,成员初始化列表的具体行为到底是什么呢?

成员初始化列表和构造函数体的区别

成员初始化列表和构造函数的函数体都可以为我们的类数据成员指定一些初值,但是两者在给成员指定初值的方式上是不同的。成员初始化列表使用初始化的方式来为数据成员指定初值,而构造函数的函数体是通过赋值的方式来给数据成员指定初值。也就是说,成员初始化列表是在数据成员定义的同时赋初值,但是构造函的函数体是采用先定义后赋值的方式来做。这样的区别就造成了,在有些场景下,是必须要使用成员初始化列表的。

功能上面的区别

  1. 初始化一个引用成员变量
  2. 初始化一个const变量
  3. 当我们在初始化一个子类对象的时候,而这个子类对象的父类有一个显示的带有参数的构造函数
  4. 当调用一个类类型成员的构造函数,而它拥有一组参数的时候

在这四种情况下是必须要使用成员初始化列表来为这些类型的成员赋初值的。因为这些成员都必须用初始化的方式赋初值。比如引用和const成员变量,这些都是不接受定义之后的赋值的。而对于3的话,是因为子类对象包括父类对象,父类对象既然明确指定了带参的构造函数,那么就必须在构造子类对象的父类部分时显示调用这个构造函数,是不能依赖于合成的默认构造函数的,而这样的话,就必须在成员初始化列表中调用。4也一样,类类型的成员所在类如果有显示定义的构造函数那么也是需要在定义这个成员的同时需要显示调用的。

如果一个类中有这些类型成员的话,是必须要使用成员初始化列表的。

性能上面的区别

假设有这样一个类:

class word
{
    String _name;
    int _cnt;
public:
    word(){_name = 0; _cnt = 0}    
};

如果我们创建这样的一个类对象的话,我们可以看出它是用构造函数的函数体来完成数据成员的付初值操作的。对于普通的内置类型还好,但是当有类类型的成员的时候,成员初始化列表和构造函数体两种赋初值的效率就有区别了。

上述代码中的构造函数会被编译器扩展成如下形式:

word::word()
{
    _name.String::String();

    String temp = String(0);

    _name.String::operator=(temp);

    temp.String::~String();

    _cnt = 0;
}

可以看出,如果使用构造函数体来对类类型付初值的时候,平白无故多了很多步骤和花销。

  • 一次默认构造函数的调用
  • 一个临时对象temp的创建
  • 一次拷贝赋值运算符函数的调用
  • 一次析构函数的调用

如果我们现在改成成员列表来初始化呢?

word::word()
{
    _name.String::String(0);
    _cnt = 0;
}

代码果然简洁了许多,也减少了很多花销,前面的方法使用的是拷贝赋值运算符来给数据成员赋初值,而后面的方法是使用类的拷贝构造函数来赋初值。

成员初始化列表的行为

成员初始化列表是可以初始化类的数据成员,那么他是如何操作的呢?是通过一系列的函数调用么,不是的。成员初始化列表是按照数据成员的声明顺序,将初始化操作安排在构造函数所有usercode的前面。成员初始化列表的初始化顺序是按照类成员的声明顺序来的,所以在初始化的时候,尽量不要用次序较后的成员来初始化次序较前的成员,这样就会出问题,这也是成员初始化列表的一个弊端。

总结

成员初始化列表是有弊端的,但是在效率和一些特殊的场合下是非常有用的。如果类有中类类型的成员的话,成员初始化列表还是很好用的,但是如果仅仅只是一些内置数据类型的话,成员初始化列表和构造函数体的使用是没有什么区别的。


原作链接

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
静态成员是指在类中使用static关键字声明的成员。它们不依赖于类的实例化,而是与类本身相关联。静态成员具有以下几个特点: 1. 静态成员属于类,而不属于类的实例。这意味着无论创建多少个类的实例,静态成员只有一个副本,被所有实例共享。 2. 静态成员可以直接通过类名访问,而无需实例化类对象。例如,可以通过ClassName.staticMember的形式来访问静态成员。 3. 静态成员在类的初始化阶段被创建,并在整个程序的执行过程中存在。它们会在程序启动时进行初始化,直到程序结束时才会被销毁。 4. 静态成员可以访问类的非静态成员,但非静态成员无法直接访问静态成员。这是因为静态成员的存在不依赖于类的实例,而非静态成员的访问需要通过实例化类对象。 5. 静态成员可以用于共享数据或者统计类的实例个数等功能。例如,可以使用一个静态成员变量来记录类的实例数目。 需要注意的是,静态成员在内存中只有一份副本,如果对静态变量进行修改,那么这个修改会对所有实例产生影响。此外,静态成员还可以通过静态成员函数来访问和修改,这些静态成员函数也不依赖于类的实例。 总之,静态成员是与类相关联的成员,具有独特的访问方式和生命周期。它们在编写程序时具有一定的灵活性和实用性,可以用于共享数据和实现功能的统计等方面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值