类与对象(三)--构造函数体中的赋值和初始化列表的区别

简介: 类与对象(三)--构造函数体中的赋值和初始化列表的区别

🎧1构造函数体赋值

🔎在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

⭐️就像上述代码中的构造函数,其函数体的语句只能被称为赋予初值而不能称为初始化。因为初始化是在定义的同时赋值且只赋值一次,而构造函数体内是先定义后赋值。

🎧2初始化列表

2.1什么叫初始化列表?

🔎在C++中,构造函数的初始化列表是一种用于在创建对象时对成员变量进行初始化的特殊语法。它出现在构造函数的函数体之前使用冒号 : 分隔构造函数的参数列表和初始化列表,初始话列表中的语句用逗号“,”隔开

2.2初始化列表的作用?

🔎可以在对象创建时直接对成员变量进行初始化,而不需要在构造函数的函数体中再次进行赋值操作。这可以提高代码效率,并且在一些情况下是必要的,例如对于常量成员变量或引用成员变量。

2.3使用举例

🔎 以上代码乍一看这初始化列表和函数体赋值好像就是使用方式不一样。实则不然。就从功能角度来说,初始化列表只能用于初始化。而构造函数体中,可以实现其它的操作,比如打印。

2.4初始化列表的具体使用细则

1.每个成员在初始化列表中只能出现一次(初始化只能初始一次)

2.类中包含以下成员,必须放在初始化列表位置进行初始化

🔥引用成员变量

🔥const成员变量

🔥自定义类型成员变量(且该类没有默认构造函数)

💬引用成员变量比较好理解,因为之前我们已经讲过引用类型的变量必须初始化且不能被再次赋值。const成员变量无法被赋值,只能放在初始化列表进行初始化,而自定义类型如果没有默认的构造函数的话(编译器生成的无参的),也就不能先定义后再赋值,且该类里面也可能又引用或者const成员变量,所以必须再定义的同时初始化。

3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。

4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后
次序无关。

举例:

观察以下代码

class A
{
public:
  A(int a)
    :_a1(a)
    , _a2(_a1)
  {}
  void Print() {
    cout <<"a1=" << _a1 << " " <<"a2=" << _a2 << endl;
  }
private:
  int _a2;
  int _a1;
};
void test1() {
    A aa(1);
  aa.Print();
}

如果调用函数test1()会输出什么呢?

💬我们可以看到,虽然再初始化列表中_a1的顺序在_a2前面,但是由于声明顺序是_a2先声明,所以先初始化_a2.也就是先将_a1的值赋给_a2,但是由于此时的_a1并没有初值是一个随机值,所以会得到这样的结果。

🎧3两者的区别🚦

  1. 执行时机:
  • 初始化列表: 初始化列表会在进入构造函数的函数体之前执行,即在构造函数开始执行之前。这确保了在进入函数体之前,所有的成员变量都已经得到了适当的初始化。
  • 构造函数体内的赋值: 构造函数体内的赋值则是在进入构造函数的函数体后执行的操作。

语法形式:

  • 初始化列表: 使用冒号 : 后面跟着成员变量的初始化语句。
  • 构造函数体内的赋值: 在构造函数的函数体内,通过赋值语句对成员变量进行初始化。

🎧4总结🚦

在实践中,推荐使用初始化列表,特别是对于非静态常量成员、引用成员或具有自定义构造函数的成员。这样可以确保在进入构造函数体之前,所有成员都得到了正确的初始化。

相关文章
|
NoSQL MongoDB 存储
MongoDB 一致性模型设计与实现
本文源自阅读了 MongoDB 于 VLDB 19 上发表的 [Tunable Consistency in MongoDB](http://www.vldb.org/pvldb/vol12/p2071-schultz.pdf) 论文之后,在内部所做的分享(分享 PPT 见文末)。现在把分享的内容整理成此文,并且补充了部分在之前的分享中略过的细节,以及在分享中没有提及的 MongoDB Causa
2354 152
MongoDB 一致性模型设计与实现
|
小程序 安全 数据安全/隐私保护
微信小程序全栈开发中的身份认证与授权机制
【4月更文挑战第12天】本文探讨了微信小程序全栈开发中的身份认证与授权机制。身份认证包括手机号验证、微信登录和第三方登录,而授权机制涉及角色权限控制、ACL和OAuth 2.0。实践中,开发者可利用微信登录获取用户信息,集成第三方登录,以及实施角色和ACL进行权限控制。注意点包括安全性、用户体验和合规性,以保障小程序的安全运行和良好体验。通过这些方法,开发者能有效掌握小程序全栈开发技术。
936 0
|
存储 程序员 C语言
动态存储方式与静态存储方式
在编程中,数据的存储方式对于程序的性能、内存使用以及代码的可维护性都有着至关重要的影响。其中,动态存储方式和静态存储方式是两种常见的数据存储方式。本文将探讨这两种存储方式的区别、应用场景,并附上相应的代码示例。
829 1
|
机器学习/深度学习 人工智能 编译器
【AI系统】Auto-Tuning 原理
本文探讨了在多样化硬件平台上部署深度神经网络(DNN)时,传统算子库面临的挑战及解决方案。随着硬件平台的多样化和快速迭代,手动编写高性能算子库变得日益困难。文中介绍了基于TVM的三种自动调优系统——AutoTVM、Ansor和Meta Scheduler,它们通过自动生成高性能算子,有效解决了传统方法的局限性,提高了DNN在不同硬件平台上的执行效率。
610 1
|
存储 人工智能 程序员
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
588 1
|
安全 算法 Shell
PWN练习---Heap_1
PWN练习---Heap_1
396 7
|
机器学习/深度学习 人工智能 算法
程序员必知:VS2017动态链接库(.dll)的生成与使用
程序员必知:VS2017动态链接库(.dll)的生成与使用
394 3
|
存储 数据处理 索引
数据类型转换:int()、str()、float()
在Python中,数据类型转换是一项基础且重要的操作
|
数据安全/隐私保护 C++
C++ 构造函数实战指南:默认构造、带参数构造、拷贝构造与移动构造
C++中的构造函数是特殊成员函数,用于对象初始化。类型包括默认构造函数(无参数)、带参数构造函数、拷贝构造函数和移动构造函数。默认构造函数设置对象默认状态,带参数构造函数允许传递初始化值。拷贝构造函数复制已有对象,移动构造函数高效转移资源。构造函数的访问权限可控制为public、private或protected。理解构造函数有助于编写健壮的C++代码。关注公众号`Let us Coding`获取更多内容。
528 0

热门文章

最新文章