C++之初始化列表详细剖析

这篇具有很好参考价值的文章主要介绍了C++之初始化列表详细剖析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、初始化列表定义

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)//初始化列表
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

二、初始化列表内在作用的剖析

不知道大家有没有想过这样一个问题,成员函数明明可以在函数内部对成员变量进行赋值,那为什么还要搞出初始化列表这个东西呢?这个时候就需要我们对初始化列表有一个更加深刻的理解了。

我们知道,在一个类被设计出来的时候,它里面定义的成员变量只是变量的声明,没有为其分配空间。我们也知道,类定义出一个对象是在主函数中定义的,而创建出来的这个对象其中的成员变量其实是在初始化列表中定义的。那么假设我们创建出来的类的成员变量中含有引用类型或者是被const修饰时(引用类型和const修饰的变量在定义时就必须为其赋初始值),就像下面这个代码:

C++之初始化列表详细剖析,c++,开发语言

 如果我们定义的类内部的成员变量中含有引用类型或者是被const修饰,而在成员函数体内部再对其赋初始值,就相当于_ref和_n两个变量定义和赋初始值分离了,但我们明确地知道引用类型或者是被const修饰的变量在定义时就必须为其赋初始值,所以编译器会报未初始化的错误。上面图片中的代码还可以写的更明确一点,就相当于下面这种形式:

C++之初始化列表详细剖析,c++,开发语言

 五个成员变量全部定义和赋初始值分开,一般的内置类型是支持这种行为的。就像是这样:

int main()
{
	int a;
	a = 10;//可以
	int& n;
	n = a;//报错
	const int m;
	m = 10;//报错
	return 0;
}

所以正确的方法应该是:类内部的成员变量中含有引用类型或者是被const修饰时,引用类型或者是被const修饰的成员变量必须用初始化列表赋初值(定义时就赋初值)。

class Date
{
private:
	int _year;
	int _month;
	int _day;
	int& _ref;
	const int _n;

public:
	Date(int year, int month, int day)
		:_year()
		,_month()
		,_day()
		,_ref(month)
		,_n(1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
};

三、类中成员变量含有自定义类型的情况

很好理解,自定义也必须使用初始化列表进行初始化,如果自定义类型没有显示地调用初始化列表,那么自定义类型就会去调用它的默认构造函数,如果没有默认构造函数,就会编译报错。

#include <iostream>
using namespace std;


class A
{
private:
	int _a;

public:
	A(int a = 0)
	{
		this->_a = a;
	}
};


class Date
{
private:
	int _year;
	int _month;
	int _day;
	A aa;
	int& _ref;
	const int _n;

public:
	Date(int year, int month, int day)
		:_year()  //aa没有显示地调用初始化列表,会去调用它的默认构造函数
		, _month()//剩下的三个成员没有写出来定义,但是它也会定义,只是内置类型给的随机值
		, _day()  //自定义类型会去调用它的默认构造函数
		,_ref(month)
		,_n(1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
};


//编译没有报错
int main()
{
	Date d1(2023, 11, 2);
	return 0;
}

C++之初始化列表详细剖析,c++,开发语言

 _a被初始化为了0。还是上面这段代码,如果将A(int a = 0)改成A(int a),编译就会报错,因为没有合适的默认构造函数。

C++之初始化列表详细剖析,c++,开发语言

所以自定义类型在使用初始化列表的时候,建议要显示地传参去调用指定的构造函数。

四、初始化列表使用的建议以及小点

尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。
但是我们能不能什么地方都用初始化而都不在函数体内部赋初始值呢?答案是不行的。初始化列表可以解决百分之九十的问题,但对于一些像判断之类的语句还是要放在函数体内部的。像下面这个例子:
class Date
{
private:
	int _year;
	int _month;
	int _day;
	int* _aa;

public:
	Date(int year, int month, int day)
		:_year(year)  //aa没有显示地调用初始化列表,会去调用它的默认构造函数
		, _month(month)//剩下的三个成员没有写出来定义,但是它也会定义,只是内置类型给的随机值
		, _day(day)  //自定义类型会去调用它的默认构造函数
		,_aa(new int [10])
	{

		if (_aa == nullptr)
		{
			perror("new fail");
			exit(-1);
		}
	}

	~Date()
	{
		delete[] _aa;
	}
};


int main()
{
	Date d1(2023, 11, 2);
	return 0;
}

这里有一个小点需要注意:. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}

	void Print() 
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};


int main() 
{
	A aa(1);
	aa.Print();
}

上面代码_a2比_a1先声明,所以_a2先初始化,用_a1初始化_a2,此时_a1为随机值,所以初始化完_a2为随机值,再用1初始化_a1,_a1为1。

C++之初始化列表详细剖析,c++,开发语言文章来源地址https://www.toymoban.com/news/detail-742008.html

到了这里,关于C++之初始化列表详细剖析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】构造函数和初始化列表的性能差距

    构造函数和初始化列表的性能差距对比测试 在C++类和对象中,你可能听到过更加推荐用初始化列表来初始化类内成员。如果类内成员是自定义类型,则只能在初始化列表中调用自定义类型的构造函数。 但初始化列表和在构造函数体内直接赋值有无性能差距呢?今天就用一份

    2024年02月11日
    浏览(44)
  • 【C++】初始化列表构造函数VS普通构造函数

    初始化列表构造函数最优先匹配问题 对于一个类而言,只要其中包含有初始化列表的构造函数,编译器在编译使用{}语法的构造时会最倾向于调用初始化列表构造函数,哪怕做类型转换也在所不惜,哪怕有类型最佳匹配的普通构造函数或移动构造函数也会被劫持 编译器这种热

    2024年02月05日
    浏览(70)
  • C++——初始化列表 | explicit关键字 | static成员

    🌸作者简介: 花想云 ,在读本科生一枚,致力于 C/C++、Linux 学习。 🌸 本文收录于 C++系列 ,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新! 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列 、 数据结构与算法 本章我们

    2023年04月11日
    浏览(50)
  • 【C++基础(六)】类和对象(下)--初始化列表,友元,匿名对象

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++初阶之路⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 关于类和对象的大致内容已经结束 本篇文章主要是介绍一些冗杂的细节 虽然本节的内容属于对类和对象锦上添花 但在很多特定的场所下,还是

    2024年02月14日
    浏览(63)
  • 【C++】初始化列表、static成员、友元、匿名对象、附练习题

    我们前面学习了关于类和对象的6个默认成员函数,知道了一个空类中有构造函数和析构函数,通过对对象初始化和对象中进行资源清理,达到初始化和销毁的作用。我们再对一些小的点进行补充,看看类和对象的一些细节。 1.1 构造函数体赋值 在创建对象时,编译器通过 调

    2024年02月22日
    浏览(52)
  • 【C++基础】类与对象(下) 初始化列表、友元、内部类、匿名对象

    ​👻内容专栏: C/C++编程 🐨本文概括: C++基础语法。初始化列表、 explicit 、 static 成员、友元、内部类、匿名对象、拷贝对象时的一些编译器优化等。 🐼本文作者: 阿四啊 🐸发布时间:2023.9.8 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个

    2024年02月09日
    浏览(50)
  • 【C++初阶】六、类和对象(初始化列表、static成员、友元、内部类)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【C++初阶】五、类和对象 (日期类的完善、流运算符重载函数、const成员、“”取地址运算符重

    2024年02月05日
    浏览(44)
  • 【C++】类与对象 第三篇(初始化列表,explicit,static,友元,内部类)

    目录 再谈构造函数 构造函数体赋值 初始化列表 explicit static成员 匿名对象 友元 友元函数 友元类 内部类 拷贝对象时的一些编译器优化 在创建对象时,编译器通过调用构造函数给对象各个成员变量一个合适的初始值 虽然上述构造函数调用之后,对象中已经有了一个初

    2024年02月05日
    浏览(47)
  • c++类和对象(拷贝构造、运算符重载、初始化列表、静态成员、友元等)

    拷贝构造函数的特征: 1、拷贝构造函数是构造函数的一个重载形式; 2、拷贝构造函数的参数只有一个且必须是同类类型对象的引用, 使用传值方式编译器直接报错 ,因为会引发无穷递归调用。 在c++中自定义类型 传值传参 的时候要调用拷贝构造函数。 3、若未显式定义,

    2024年02月15日
    浏览(37)
  • 【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名对象)

    目录 一、初始化列表 ⭕初始化列表概念 ⭕初始化列表的优点 ⭕使用场景 ⭕explicit 二、Static成员 ⭕Static成员概念 🔴静态数据成员: 🔴静态函数成员: ⭕使用静态成员的优点 ⭕使用静态成员的注意事项 三、友元 ⭕友元的概念 ⭕类友元 ⭕函数友元  四、内部类 ⭕

    2024年02月14日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包