由C++构造函数初始值列表想到的

本文探讨了C++中构造函数使用初始值列表的重要性,尤其是在处理const成员变量、引用及自定义类型时。当数据成员为自定义类型且无默认构造函数时,必须使用初始值列表进行初始化。

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

引子

大家在编写C++代码的时候,总是会遇到下面这个问题,什么时候为构造函数提供初始值列表(当然,推荐做法都是以初始值列表代替构造函数体内赋值)。数据成员初始化动作是在构造函数体之前的,相对应的,析构函数的数据成员销毁动作是在析构函数体之后的。所常见的必须提供初始值列表的情况有,

  • 数据成员含有const成员变量
  • 数据成员含有引用

前面两个比较好理解,const和引用都是必须在声明时赋初值的。但是数据成员中有自定义类型时,就要考虑自定义类型有没有默认构造函数了,例如下面代码:

class B{
public:
    int mem;
    B(int para) : mem(para) {}
};

class A{
public:
    B mem_b;
    A(int para) 
    { 
        // 注意这种赋值有一个隐式操作
        // mem_b = static_cast<B>(mem);
        // 或
        // mem_b = temp(mem);
        // 然后再调用拷贝赋值运算符赋值给mem_b
        mem_b = mem; 
    }
};

上述代码编译是不会通过的,因为数据成员mem_b没有提供默认构造函数,所以在进入函数体赋值之前,是要报错的。注意,如果自定义类型没有提供拷贝赋值运算符,编译器会为其提供合成的拷贝赋值运算符执行简单内存拷贝操作。

但是为什么人们经常会忽视第三种情况呢,这是由于人们有个误区。

下意识将内置类型和自定义类型分开

其实自定义类型和内置类型说到底都是类型,都是描述数据在内存中的组织方式和对应的操作。这样说是不严谨的,编译原理中对数据类型的定义是,一组值得集合,以及对这组值进行的操作(运算)的集合。数据在计算机内存中无非是二进制位串的集合,本身没有任何意义,有意义的是如何对其进行解释。

任何语言都有自定义类型,如果语言只有内置类型那么语言的易用性就会有很大折扣。自定义类型是由自定义类型和或者是内置类型的集合构成的,是由现有类型的笛卡尔积表示的。但是自定义类型是有前提的,就是不能存在递归情况,如下所示,

class A{
public:
    int mem;
    A mem_a;
};

这种情况下,编译器对类型A的推导是不会终止的。所以C++规定自定义类型时,需要数据成员是完整类型。

自定义类型与内置类型没什么区别,都是一组值的集合和在这些值上的操作。只是这种类型的值域,以及其上的操作需要用户自己来控制,所以有许多情况需要用户注意。相对应的,类模版是构造自定义类型的模板,让用户在编写代码时能够动态定义用户类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值