前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【C++】构造函数初始化列表 ⑤ ( 匿名对象 生命周期 | 构造函数 中 不能调用 构造函数 )

【C++】构造函数初始化列表 ⑤ ( 匿名对象 生命周期 | 构造函数 中 不能调用 构造函数 )

作者头像
韩曙亮
发布2023-10-15 17:13:09
发布2023-10-15 17:13:09
24000
代码可运行
举报
运行总次数:0
代码可运行
构造函数初始化列表 总结 :
  • 初始化列表 可以 为 类的 成员变量 提供初始值 ;
  • 初始化列表 可以 调用 类的 成员变量 类型的 构造函数 进行成员变量初始化操作 ;
  • 初始化列表 可以 使用 构造函数 中传入的 参数 ;
  • 类初始化时 , 根据定义顺序 , 先调用 成员变量的 构造函数 , 然后调用外部类构造函数 , 析构函数正好相反 ;
  • 实例对象 的 const 成员变量 必须只能在 初始化列表 中进行 初始化 , 所有的构造函数都要进行初始化操作 ;
  • 构造函数 中 不能调用 构造函数 ;

一、匿名对象 生命周期

1、匿名对象 生命周期 说明

调用 类名(构造函数参数) 创建的是 匿名对象 ;

匿名对象 的 生命周期 仅限于 该 匿名对象 所在的 代码表达式 ,

一旦 该行代码执行完毕 , 匿名对象就会被销毁 ;

匿名对象 的 生命周期 仅限于 那一行代码 中 ;

匿名对象 生命周期 分以下几种情况 :

  • 单独创建 匿名对象 , 不使用变量 接收该 匿名对象 , 匿名对象 的生命周期 仅限于 创建匿名对象 的那一行代码表达式 , 一旦该行代码执行完毕 , 匿名对象 就会被销毁 ;
  • 如果 匿名对象 被用于 对象初始化 , 匿名对象 不会被销毁 , 而是被转为 普通对象 , 赋值给变量 ;
  • 如果 匿名对象 被用于 为现存对象赋值 , 会将 匿名对象 的值赋值给 现有对象 , 赋值完毕后 , 匿名对象仍在本行代码执行结束后销毁 ;

2、代码示例 - 匿名对象 生命周期

下面的代码中 , 在 fun 函数中 , 调用 Student(18, 180) 代码 , 创建 Student 类型的匿名对象 , 匿名对象的生命周期 只存在于 这一行代码 , 该行代码执行完毕后 , 匿名对象 就会被 析构 ;

代码语言:javascript
代码运行次数:0
运行
复制
void fun()
{
	cout << "创建匿名对象之前" << endl;
	// 创建 Student 类型的匿名对象
	// 匿名对象的生命周期 只存在于 这一句话
	Student(18, 180);
	cout << "创建匿名对象之后" << endl;
}

代码示例 :

代码语言:javascript
代码运行次数:0
运行
复制
#include "iostream"
using namespace std;

class Student
{
public:
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 Student 的构造函数" << endl;
	}

	~Student()
	{
		cout << "执行 Student 的析构函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};

void fun()
{
	cout << "创建匿名对象之前" << endl;
	// 创建 Student 类型的匿名对象
	// 匿名对象的生命周期 只存在于 这一句话
	Student(18, 180);
	cout << "创建匿名对象之后" << endl;
}


int main()
{
	// 该函数中定义了一个匿名对象
	fun();


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

代码语言:javascript
代码运行次数:0
运行
复制
创建匿名对象之前
执行 Student 的构造函数
执行 Student 的析构函数
创建匿名对象之后
Press any key to continue . . .

二、构造函数 中调用 构造函数


1、构造函数 中 不能调用 构造函数

构造函数中 调用 构造函数 是危险行为 ;

构造函数 中调用 构造函数 , 并不会为本对象进行初始化操作 ;

构造函数 的调用方式 , 天然就会创建一个 匿名对象 ,

如果 没有变量 接收 这个 匿名对象 , 该匿名对象 在 本行表达式执行完毕后 , 就会被销毁 ;

2、代码示例 - 构造函数中调用构造函数

下面的代码中 ,

先定义 有参构造函数 ,

代码语言:javascript
代码运行次数:0
运行
复制
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 Student 的构造函数" << endl;
	}

然后 , 在无参的 构造函数中 , 调用 有参构造函数 ;

代码语言:javascript
代码运行次数:0
运行
复制
	// 构造函数中 调用 构造函数 是危险行为
	Student()
	{
		// 构造函数中调用构造函数
		// 此时 创建 的是匿名对象
		// 如果 匿名对象 没有被接收 
		// 就会在 本代码 执行结束后 立刻销毁
		Student(18, 180);
	}

Student(18, 180) 调用方式 , 会创建一个 匿名对象 ;

如果 匿名对象 没有被接收 , 就会在 本代码 执行结束后 立刻销毁 ;

本实例对象 的成员变量实际上没有进行初始化 , 当前为随机值 ;

这也是 打印 对象成员变量 的值为随机值 的原因 ;

代码语言:javascript
代码运行次数:0
运行
复制
s.m_age = -858993460 , s.m_height = -858993460

代码示例 :

代码语言:javascript
代码运行次数:0
运行
复制
#include "iostream"
using namespace std;

class Student
{
public:
	// 带参构造函数
	Student(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 Student 的构造函数" << endl;
	}

	// 构造函数中 调用 构造函数 是危险行为
	Student()
	{
		// 构造函数中调用构造函数
		// 此时 创建 的是匿名对象
		// 如果 匿名对象 没有被接收 
		// 就会 本代码 执行结束后 立刻销毁
		Student(18, 180);
	}

	~Student()
	{
		cout << "执行 Student 的析构函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};

void fun()
{
	// 创建 Student 类型的匿名对象
	// 匿名对象的生命周期 只存在于 这一句话
	Student(18, 180);
}


int main()
{
	// 该函数中定义了一个匿名对象
	//fun();

	Student s;
	cout << "s.m_age = " << s.m_age << " , s.m_height = " << s.m_height << endl;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

代码语言:javascript
代码运行次数:0
运行
复制
执行 Student 的构造函数
执行 Student 的析构函数
s.m_age = -858993460 , s.m_height = -858993460
Press any key to continue . . .
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 构造函数初始化列表 总结 :
  • 一、匿名对象 生命周期
    • 1、匿名对象 生命周期 说明
    • 2、代码示例 - 匿名对象 生命周期
  • 二、构造函数 中调用 构造函数
    • 1、构造函数 中 不能调用 构造函数
    • 2、代码示例 - 构造函数中调用构造函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档