初始化列表

一:声明,定义,赋值的区别

①:声明

这里,int _year; int _month;int _day; 是成员变量的声明,它们告诉编译器:

  • 类 Date中有三个成员变量_year_month和_day

  • 它们的类型分别都是 int

此时,编译器并没有为 ab 分配内存,因为类的定义只是一个蓝图,只有在创建类的对象时,才会为这些成员变量分配内存。

②:定义

cpp 复制代码
int main()
{
  Date d1;//这叫定义

  return 0;
}

成员变量的定义 实际上发生在创建类的对象时,当创建 Date 的对象 d1 时,编译器会为 d1 的成员变量分配内存。这时成员变量才真正被定义(即分配了内存空间)。

③:赋值

在构造函数体内这里,构造函数体内通过赋值操作改变成员变量的值

二:为何要有初始化列表

有三种值,必须在定义的时候立刻赋予初始值 如下:

**A:**那意思是我们之前的构造函数的体内不叫立刻赋予初始值?

Q: 是的,构造函数体内对成员变量的操作不叫"立刻赋予初始值" ,而是赋值,因为构造函数体内的操作是在成员变量已经存在(已经分配内存)后,再改变它们的值,这叫作赋值。

++为什么这三种值必须在定义时立马初始化?++

这些成员变量的特性决定了它们必须在定义时立马初始化:

  1. 常量成员变量(const):

    • 常量一旦初始化后,其值不能被修改。

    • 因此,必须在定义时赋予初始值。

  2. 引用成员变量:

    • 引用必须在定义时绑定到一个对象,且之后不能重新绑定。

    • 因此,必须在定义时赋予初始值。

  3. 没有默认构造函数的类类型成员变量:

    • 如果类没有默认构造函数,则必须通过参数化构造函数初始化。

    • 因此,必须在定义时赋予初始值。

所以C++创建一个叫初始化列表,初始化列表会让这三种值在定义的时候就能被立刻赋予初始值

**初始化列表:**以一个冒号开始,逗号间隔的数据成员列表。

cpp 复制代码
class MyClass {
public:
    

    MyClass(int x, int& r, int m) 
    : a(x), ref(r), member(m)     //冒号开始,逗号间隔
    {
        // 正确:使用初始化列表初始化
    }

private:
    const int a; // 常量成员变量
    int& ref;    // 引用成员变量
    MyMemberClass member; // 没有默认构造函数的类类型成员变量
};

三: 初始化列表的注意事项

① :每个成员变量再初始化列表中只能出现一次,即 初始化只能初始化一次

cpp 复制代码
    MyClass(int x, int& r, int m) 
    : a(x), a(x),ref(r), member(m) //只能出现一次!!!
    {
        
    }

②:成员变量在类中的声明顺序就是在初始化列表中的初始化顺序,与其在初始化列表中出现的顺序无关。

++用一道题来理解②:++

cpp 复制代码
class A {
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)  // 先执行它
	{}
 
	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;   // _a2 先声明
	int _a1;
};
 
int main() {
	A aa(1);
	aa.Print();
}

此时的结果是:

解释:

因为我们先声明的是 _a2,所以在初始化列表里我们先初始化的是 _a2,因为这里是 _a2(_a1), _a1 此时还是没有得到传过去的 1,所以此时_a1还是随机值,所以 _a2 就被初始化成随机值了。按照声明顺序然后是 _a1, _a1 接收到了1,自然会初始化成 1,最后按顺序打印c 1 和 随机值。

复制代码
相关推荐
AI小老六2 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术3 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序3 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
Asize4 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
敲代码的彭于晏4 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev5 小时前
ButterKnife → ViewBinding
android·java·kotlin
罗西的思考17 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
CSharp精选营20 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
美团技术团队20 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
像我这样帅的人丶你还21 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端