Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )

【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )

作者头像
韩曙亮
发布于 2023-10-15 08:58:42
发布于 2023-10-15 08:58:42
55700
代码可运行
举报
运行总次数:0
代码可运行

一、构造函数分类

1、构造函数分类简介

C++ 构造函数可以分为以下几类 :

  • 无参构造函数 : 最简单也是默认的构造函数 , 函数没有参数 , 如果创建一个对象 , 没有传入参数 , 调用的就是该类型的 构造函数 ;
  • 有参构造函数 : 带参数的 构造函数 , 创建 实例对象 时 , 为成员变量提供初始值 ;
  • 拷贝构造函数 : 拷贝现有 实例对象 , 并以此拷贝的副本为数据 创建一个新的 实例对象 , 相当于创建了一个现有实例对象的副本 , 参数中包含 一个 相同类型 实例对象 引用 ;

2、构造函数分类代码分析

定义成员变量 : 下面的简介示例中是以该成员变量为基础进行赋值的 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public:
	int m_age;
	char* m_name;
无参构造函数

无参构造函数 : 只负责为指针类型的成员变量分配内存 , 并赋值一个初始值 , 没有具体的赋值信息 , 该初始化只能为 成员变量 赋值一个默认值 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 无参构造函数
Student()
{
	// 为 m_name 成员分配内存
	m_name = (char*)malloc(100);

	// 为 m_name 成员设置字符串值
	if(m_name != NULL)
	{
		strcpy_s(m_name, 5, "name");
	}
	
	// 为 m_age 成员设置初始值
	m_age = 0;

	cout << "调用无参构造函数" << endl;
}

下面的代码 , 是自动调用无参构造函数 , 创建 实例对象 的方法 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 调用无参构造函数
	Student s1;
	// 打印 Student s1 实例对象值
	cout << "name : " << s1.m_name << " , age : " << s1.m_age << endl;
有参构造函数

有参构造函数 : 可以将 为 成员变量 赋值的数据放在 构造函数 参数中 , 传递进来 , 并在 构造函数 中 , 为 成员变量 赋值具体的值 ;

此处需要注意的是 , 这里传入的是 C 语言中的字符串 , 也就是 char * 类型的指针 , 传入后拷贝字符串时 , 需要判定字符串的长度 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 有参构造函数
Student(int age, const char* name)
{
	// 为 m_name 成员分配内存
	m_name = (char*)malloc(100);

	// 为 m_name 成员设置字符串值
	if (m_name != NULL)
	{
		strcpy_s(m_name, length, name);
	}

	// 为 m_age 成员设置初始值
	m_age = age;

	cout << "调用有参构造函数" << endl;
}

下面的代码 , 使用了 2 种方法 , 手动调用了 有参构造函数 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 调用有参构造函数
Student s2 = Student(18, "Tom");
// 打印 Student s1 实例对象值
cout << "name : " << s2.m_name << " , age : " << s2.m_age << endl;

有参构造函数有很多调用方法 , 下一篇博客详细分析每种调用方法的作用 ;

拷贝构造函数

拷贝构造函数 : 拷贝构造函数 也是 有参构造函数 中的一种 , 传入的是 相同类型的 常量引用 , 该引用指向的内容在函数内不可修改 ;

在 " 拷贝构造函数 " 中 , 主要读取 现有 实例对象 中每个 成员变量的值 , 将其赋值给 新创建的 实例对象 中的每个成员变量值 ;

新创建的 实例对象 , 与原来的 实例对象 只是值相同 , 数据地址完全不同 , 没有引用关系 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 拷贝构造函数
	Student(const Student& obj)
	{
		// 为 m_name 成员分配内存
		m_name = (char*)malloc(100);

		// 为 m_name 成员设置字符串值
		if (m_name != NULL)
		{
			strcpy_s(m_name, sizeof(obj.m_name), obj.m_name);
		}

		// 为 m_age 成员设置初始值
		m_age = obj.m_age;

		cout << "调用拷贝构造函数" << endl;
	}

二、代码示例 - 三种类型构造函数定义与调用


在下面的代码中 , 分别在 Student 类中定义了

  • 无参构造函数
  • 有参构造函数
  • 拷贝构造函数

分别调用了上述三种类型的 构造函数 ;

完整代码示例 :

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

class Student
{
public:

	// 无参构造函数
	Student()
	{
		// 为 m_name 成员分配内存
		m_name = (char*)malloc(100);

		// 为 m_name 成员设置字符串值
		if(m_name != NULL)
		{
			strcpy_s(m_name, 5, "name");
		}
		
		// 为 m_age 成员设置初始值
		m_age = 0;

		cout << "调用无参构造函数" << endl;
	}

	// 有参构造函数
	Student(int age, const char* name)
	{
		// 为 m_name 成员分配内存
		m_name = (char*)malloc(100);

		// 为 m_name 成员设置字符串值
		if (m_name != NULL)
		{
			strcpy_s(m_name, sizeof(name), name);
		}

		// 为 m_age 成员设置初始值
		m_age = age;

		cout << "调用有参构造函数" << endl;
	}

	// 拷贝构造函数
	Student(const Student& obj)
	{
		// 为 m_name 成员分配内存
		m_name = (char*)malloc(100);

		// 为 m_name 成员设置字符串值
		if (m_name != NULL)
		{
			strcpy_s(m_name, sizeof(obj.m_name), obj.m_name);
		}

		// 为 m_age 成员设置初始值
		m_age = obj.m_age;

		cout << "调用拷贝构造函数" << endl;
	}

	~Student()
	{
		// 销毁 name 指向的堆内存空间
		if (m_name != NULL)
		{
			free(m_name);
		}
		cout << "调用析构函数" << endl;
	}

public:
	int m_age;
	char* m_name;
};

int main()
{
	// 声明 Student 类型实例对象
	// 调用无参构造函数
	Student s1;
	// 打印 Student s1 实例对象值
	cout << "name : " << s1.m_name << " , age : " << s1.m_age << endl;

	// 手动调用有参构造函数
	// 直接调用构造函数会产生匿名对象, 涉及到该匿名对象的生命周期
	Student s2 = Student(18, "Tom");
	// 打印 Student s1 实例对象值
	cout << "name : " << s2.m_name << " , age : " << s2.m_age << endl;

	// 调用拷贝构造函数
	Student s3 = Student(s2);
	// 打印 Student s3 实例对象值
	cout << "name : " << s3.m_name << " , age : " << s3.m_age << endl;

	

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

执行结果 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
调用无参构造函数
name : name , age : 0
调用有参构造函数
name : Tom , age : 18
调用拷贝构造函数
name : Tom , age : 18
Press any key to continue . . .
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【C++】运算符重载 ⑨ ( 等号 = 运算符重载 | 调用默认浅拷贝构造函数的情况分析 | 等号 = 运算符重载 与 拷贝构造函数 各自使用场景 | 等号 = 操作符重载步骤 )
C++ 编译器 为 类 提供的 默认的 拷贝操作 , 是对 成员变量 的简单拷贝 , 是 浅拷贝 ;
韩曙亮
2023/10/15
3260
【C++】运算符重载 ⑨ ( 等号 = 运算符重载 | 调用默认浅拷贝构造函数的情况分析 | 等号 = 运算符重载 与 拷贝构造函数 各自使用场景 | 等号 = 操作符重载步骤 )
【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )
在上一篇博客 中 , 定义了 可拷贝 与 可打印 的 自定义类 Student , 可以被存放到 数组类模板 中 ;
韩曙亮
2023/11/25
2320
【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )
C++学习————第五天(构造函数 析构函数 拷贝构造函数)
关于后面三个默认函数:https://blog.csdn.net/island1314/article/details/137756026?spm=1001.2014.3001.5502
IsLand1314
2024/10/15
1380
C++学习————第五天(构造函数 析构函数 拷贝构造函数)
【C++】深拷贝和浅拷贝 ② ( 默认拷贝构造函数是浅拷贝 | 代码示例 - 浅拷贝造成的问题 )
如果 C++ 类中 没有定义拷贝构造函数 , C++ 编译器会自动为该类提供一个 " 默认的拷贝构造函数 " , 在函数中对成员变量进行简单的复制操作 ;
韩曙亮
2023/10/15
2260
【C++】深拷贝和浅拷贝 ② ( 默认拷贝构造函数是浅拷贝 | 代码示例 - 浅拷贝造成的问题 )
C++:堆与拷贝构造函数及补充this指针
在 C 语言中,我们通过 malloc 或者 calloc 申请的空间即为堆区的空间,使用完成后用 free 归还申请的内存;而在 C++ 中我们用 new 申请堆区内存,delete 释放内存。操作堆内存时,有借有还,分配了堆内存就要记得对其进行回收,当然,这在 C++ 中是一件很麻烦的事情。
字节星球Henry
2021/08/09
8260
【C++】深拷贝和浅拷贝 ③ ( 浅拷贝内存分析 )
下面的代码中 , 没有定义拷贝构造函数 , 因此 C++ 编译器会自动生成一个 只进行 浅拷贝 的 默认拷贝构造函数 ;
韩曙亮
2023/10/15
2020
【C++】深拷贝和浅拷贝 ③ ( 浅拷贝内存分析 )
【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )
上一篇博客 【C++】泛型编程 ⑬ ( 类模板示例 - 数组类模板 | 构造函数和析构函数 的 声明与实现 | 普通成员函数 的 声明与实现 | 外部友元函数 的 声明与实现 ) 中 , 实现了一个 数组 类模板 , 数组 中的 数据元素 是 泛型类型 , 可以是任意类型 ;
韩曙亮
2023/11/24
2280
【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )
【C++】构造函数分类 ③ ( 调用有参构造函数的方法 | 括号法 | 等号法 )
在上一篇博客 【C++】构造函数分类 ② ( 在不同的内存中创建类的实例对象 | 栈内存中创建实例对象 | new 关键字创建对象 ) 中 , 分析了 在 栈内存 和 堆内存 中创建对象 的 两种情况 ;
韩曙亮
2023/10/15
2610
【C++】构造函数分类 ③ ( 调用有参构造函数的方法 | 括号法 | 等号法 )
【C++修行之道】类和对象(三)拷贝构造函数
四、编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?
走在努力路上的自己
2024/05/31
1030
【C++修行之道】类和对象(三)拷贝构造函数
C++基础构造函数(constructor)
C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数,构造函数在定义时可以有参数;但是是没有任何返回类型的声明。
羊羽shine
2019/05/28
5200
【C++】深拷贝和浅拷贝 ④ ( 深拷贝示例 )
在上一篇博客 【C++】深拷贝和浅拷贝 ③ ( 浅拷贝内存分析 ) 中 , 使用了浅拷贝 , 将 原始对象 Students 赋值给了 拷贝对象 Student s2 ;
韩曙亮
2023/10/15
2540
【C++】深拷贝和浅拷贝 ④ ( 深拷贝示例 )
【C++】运算符重载案例 - 字符串类 ② ( 重载 等号 = 运算符 | 重载 数组下标 [] 操作符 | 完整代码示例 )
个对象 Student s1, s2 之间进行 等号运算 , 使用一个现有对象 为 另外一个现有对象赋值 ;
韩曙亮
2023/10/15
4180
【C++】运算符重载案例 - 字符串类 ② ( 重载 等号 = 运算符 | 重载 数组下标 [] 操作符 | 完整代码示例 )
C++的拷贝构造函数
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
鲜于言悠
2024/05/24
820
C++的拷贝构造函数
C++-面向对象(八)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/10/28
2930
C++第四弹 -- 类与对象中篇上(构造函数 析构函数 拷贝构造函数)
让我们一起揭开 C++ 对象生命周期管理的神秘面纱,掌握构造函数、析构函数和拷贝构造函数的精髓!
用户11317877
2024/10/16
1220
C++第四弹 -- 类与对象中篇上(构造函数 析构函数 拷贝构造函数)
C++之拷贝构造函数
拷贝构造函数最常见的是当我们创建的对象是用该类的另一个对象来进行初始化的,此时调用的构造函数就是拷贝构造函数。拷贝构造函数实质上就是构造函数的重载。当你不显式定义拷贝构造函数的时候,C++会给你提供一个默认拷贝构造函数,这和它提供默认构造函数是一样的。但是当你一旦显式定义了构造函数和拷贝构造函数,那么C++将不再提供默认构造函数和默认拷贝构造函数。
zy010101
2020/04/08
7440
C/C++ 类与构造析构等知识
构造/析构 函数: 构造函数与类名相同,没有返回值,不写void,可以发生重载,可以有参数
王瑞MVP
2022/12/28
4560
【C++】构造函数初始化列表 ④ ( 构造函数 和 析构函数 调用顺序分析 )
析构函数调用顺序 与 构造函数调用顺序相反 , 直接 将 构造函数 调用顺序 倒序排列即可 ;
韩曙亮
2023/10/15
3930
【C++】构造函数初始化列表 ④ ( 构造函数 和 析构函数 调用顺序分析 )
C++期末复习
(1)构造函数,这个需要注意的就是我们如果使用类名加括号,括号里面加参数的方式这样的写法不是在调用构造函数,而是在创建一个匿名对象;
阑梦清川
2025/02/24
480
C++期末复习
【C++】STL 容器 - STL 容器的值语意 ( 容器存储任意类型元素原理 | STL 容器元素可拷贝原理 | STL 容器元素类型需要满足的要求 | 自定义可存放入 STL 容器的元素类 )
C++ 语言中的 STL 容器 , 可以存储任何类型的元素 , 是因为 STL 容器 使用了 C++ 模板技术进行实现 ;
韩曙亮
2024/01/04
1730
【C++】STL 容器 - STL 容器的值语意 ( 容器存储任意类型元素原理 | STL 容器元素可拷贝原理 | STL 容器元素类型需要满足的要求 | 自定义可存放入 STL 容器的元素类 )
推荐阅读
【C++】运算符重载 ⑨ ( 等号 = 运算符重载 | 调用默认浅拷贝构造函数的情况分析 | 等号 = 运算符重载 与 拷贝构造函数 各自使用场景 | 等号 = 操作符重载步骤 )
3260
【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )
2320
C++学习————第五天(构造函数 析构函数 拷贝构造函数)
1380
【C++】深拷贝和浅拷贝 ② ( 默认拷贝构造函数是浅拷贝 | 代码示例 - 浅拷贝造成的问题 )
2260
C++:堆与拷贝构造函数及补充this指针
8260
【C++】深拷贝和浅拷贝 ③ ( 浅拷贝内存分析 )
2020
【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )
2280
【C++】构造函数分类 ③ ( 调用有参构造函数的方法 | 括号法 | 等号法 )
2610
【C++修行之道】类和对象(三)拷贝构造函数
1030
C++基础构造函数(constructor)
5200
【C++】深拷贝和浅拷贝 ④ ( 深拷贝示例 )
2540
【C++】运算符重载案例 - 字符串类 ② ( 重载 等号 = 运算符 | 重载 数组下标 [] 操作符 | 完整代码示例 )
4180
C++的拷贝构造函数
820
C++-面向对象(八)
2930
C++第四弹 -- 类与对象中篇上(构造函数 析构函数 拷贝构造函数)
1220
C++之拷贝构造函数
7440
C/C++ 类与构造析构等知识
4560
【C++】构造函数初始化列表 ④ ( 构造函数 和 析构函数 调用顺序分析 )
3930
C++期末复习
480
【C++】STL 容器 - STL 容器的值语意 ( 容器存储任意类型元素原理 | STL 容器元素可拷贝原理 | STL 容器元素类型需要满足的要求 | 自定义可存放入 STL 容器的元素类 )
1730
相关推荐
【C++】运算符重载 ⑨ ( 等号 = 运算符重载 | 调用默认浅拷贝构造函数的情况分析 | 等号 = 运算符重载 与 拷贝构造函数 各自使用场景 | 等号 = 操作符重载步骤 )
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验