C++ 中,构造函数、拷贝构造函数和移动构造函数区别

在 C++ 中,构造函数、拷贝构造函数和移动构造函数是类中用于对象初始化的三种不同类型的构造函数。它们的功能和使用场景有所不同,下面详细解释它们之间的区别。

1. 构造函数 (Constructor)

定义: 构造函数是一个特殊的成员函数,用于初始化类的对象。它在创建对象时自动调用。

特点

  • 构造函数的名称与类名相同。
  • 构造函数没有返回类型,也不能有 void 类型。
  • 可以有多个构造函数,允许不同的参数来创建对象(称为重载构造函数)。

常见类型

  • 默认构造函数:没有参数的构造函数。
  • 参数化构造函数:带有参数的构造函数。

示例

class MyClass {
public:MyClass() {  // 默认构造函数std::cout << "Default Constructor\n";}MyClass(int x) {  // 参数化构造函数std::cout << "Constructor with value: " << x << "\n";}
};

用途:在创建对象时执行初始化操作。


2. 拷贝构造函数 (Copy Constructor)

定义: 拷贝构造函数是用于通过已有对象来构造一个新对象。它通常在以下情况下被调用:

  • 传值参数的函数调用时。
  • 返回一个对象时。
  • 在对象初始化时通过另一个相同类型的对象进行初始化。

拷贝构造函数的签名

ClassName(const ClassName& other);

特点

  • 拷贝构造函数的参数是同类型对象的引用,通常是常量引用 (const&)。
  • 如果没有显式定义拷贝构造函数,编译器会生成一个默认的拷贝构造函数,通常执行成员逐一拷贝。

示例

class MyClass {
public:int x;MyClass(int val) : x(val) {}MyClass(const MyClass& other) {  // 拷贝构造函数x = other.x;std::cout << "Copy Constructor\n";}
};

用途:在对象需要复制时调用,如:

  • 从函数返回对象时。
  • 传递对象到函数时按值传递。
  • 对象赋值时。

3. 移动构造函数 (Move Constructor)

定义: 移动构造函数是用于将一个临时对象(右值)转移给另一个对象的构造函数。它通常通过“偷取”资源的方式来避免不必要的拷贝操作,尤其是在处理动态内存分配和资源管理时,能够提高性能。

移动构造函数的签名

ClassName(ClassName&& other);

特点

  • 移动构造函数的参数是一个右值引用(ClassName&&),表示源对象可以被“移动”而不是被拷贝。
  • 移动构造函数通常将源对象的资源(如指针)转移给新对象,并将源对象置为有效的但不再拥有资源的状态。
  • 移动构造函数和拷贝构造函数的不同之处在于它不会进行资源的复制,而是转移资源的所有权。

示例

class MyClass {
public:int* data;MyClass(int val) {data = new int(val);std::cout << "Constructor\n";}~MyClass() {delete data;std::cout << "Destructor\n";}// 移动构造函数MyClass(MyClass&& other) noexcept {data = other.data;other.data = nullptr;  // 防止析构时释放资源std::cout << "Move Constructor\n";}
};

用途:在以下情况下会调用移动构造函数:

  • 返回一个临时对象时。
  • 使用 std::move 语句进行资源转移时。

4. 总结:三者的区别

特性构造函数拷贝构造函数移动构造函数
调用时机创建一个新的对象时调用通过已有对象复制初始化一个新对象时调用通过临时对象或右值初始化新对象时调用
参数类型没有参数或有参数同类型对象的常量引用 (const &)右值引用 (ClassName&&)
资源管理初始化对象,分配资源(如有)复制对象的资源资源的“转移”,避免复制
性能影响性能取决于构造逻辑会进行资源的复制,可能较慢高效,避免了不必要的复制操作
编译器自动生成编译器自动生成默认构造函数编译器自动生成默认拷贝构造函数编译器不会自动生成(除非特定情况)

示例代码演示:

#include <iostream>
#include <vector>class MyClass {
public:int* data;MyClass(int val) {data = new int(val);std::cout << "Constructor\n";}~MyClass() {delete data;std::cout << "Destructor\n";}// 拷贝构造函数MyClass(const MyClass& other) {data = new int(*other.data);std::cout << "Copy Constructor\n";}// 移动构造函数MyClass(MyClass&& other) noexcept {data = other.data;other.data = nullptr;std::cout << "Move Constructor\n";}
};int main() {MyClass a(10);         // ConstructorMyClass b = a;         // Copy ConstructorMyClass c = std::move(a); // Move Constructorstd::vector<MyClass> vec;vec.push_back(b);      // Copy Constructorvec.push_back(std::move(c)); // Move Constructor
}

以上代码展示了构造函数、拷贝构造函数和移动构造函数在不同情况下的调用及资源管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL执行一条update语句,期间发生了什么

客户端先通过连接器建立连接&#xff0c;连接器自会判断用户身份&#xff1b; 因为这是一条 update 语句&#xff0c;所以不需要经过查询缓存&#xff0c;但是表上有更新语句&#xff0c;是会把整个表的查询缓存清空的&#xff0c;所以说查询缓存很鸡肋&#xff0c;在 MySQL 8…

vue3监听横向滚动条的位置;鼠标滚轮滑动控制滚动条滚动;监听滚动条到顶端

1.横向取值scrollLeft 竖向取值scrollTop 2.可以监听到最左最右侧 3.鼠标滚轮滑动控制滚动条滚动 效果 <template><div><div class"scrollable" ref"scrollableRef"><!-- 内容 --><div style"width: 2000px; height: 100…

深入理解MyBatis的Mapper层:让数据访问更高效

目录 1. 什么是MyBatis的Mapper层&#xff1f; 1.1 典型的Mapper层结构 1.2 示例&#xff1a;一个简单的用户管理系统 2. 创建Mapper层 2.1 创建实体类 2.2 创建Mapper接口 2.3 创建Mapper XML文件&#xff08;可选&#xff09; 2.4 配置MyBatis的SQL映射 3. 使用Mapp…

WPF xaml 文件详解

<div id"content_views" class"htmledit_views"><h2><a name"t0"></a>1.总述</h2> 创建好了WPF项目后&#xff0c;最重要的是对 App和MainWindow的理解&#xff0c;在一开始的时候&#xff0c;极容易就直接在Main…

鸿蒙开发-ArkTS 创建自定义组件

在 ArkTS 中创建自定义组件是一个相对简单但功能强大的过程。以下是如何在 ArkTS 中创建和使用自定义组件的详细步骤&#xff1a; 一、定义自定义组件 使用Component注解&#xff1a;为了注册一个组件&#xff0c;使其能够在其他文件中被引用&#xff0c;你需要使用Component…

Golang学习笔记_05——延迟调用

Golang学习笔记_02——函数 Golang学习笔记_03——匿名函数和闭包 Golang学习笔记_04——递归函数 文章目录 延迟调用1. 延迟调用1.1 使用场景1.2 示例 2. panic2.1 使用场景2.2 示例 3. recover3.1 使用场景3.2 示例 源码 延迟调用 在Go语言中&#xff0c;延迟调用&#xff0…

防范TCP攻击:策略与实践

TCP&#xff08;传输控制协议&#xff09;是互联网通信的核心协议之一&#xff0c;它确保了数据在网络上的可靠传输。然而&#xff0c;TCP也容易成为各种网络攻击的目标&#xff0c;如SYN洪水攻击、TCP连接耗尽攻击等。本文将探讨如何通过配置防火墙规则、优化服务器设置以及采…

水表的数字表盘分割数据集labelme格式3023张13类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;3023 标注数量(json文件个数)&#xff1a;3023 标注类别数&#xff1a;13 标注类别名称:["readbox_1","center",&q…

【go语言】reflect包与类型推断

reflect 包的核心概念 Go 中的反射涉及两个核心概念&#xff1a; Type&#xff1a;表示一个类型的结构体&#xff0c;reflect.Type 是类型的描述。Value&#xff1a;表示一个值的结构体&#xff0c;reflect.Value 是一个具体值的包装。 反射让我们能够动态地访问对象的类型和…

跟着AI 学 AI, 开发一个ChatBot, 集成 Json 数据和查询

按照规律&#xff0c;使用AI生成一个架构图 直接上代码&#xff0c;为了方便学习&#xff0c;直接按照如下方式&#xff0c;复制到你的开发环境即可调试&#xff0c;运行代码。做学习参考。 代码注释多次说明这里&#xff0c;不在赘述。 "type": "carousel&qu…

WPF+MVVM案例实战与特效(三十七)- 实现带有水印和圆角的自定义 TextBox 控件

文章目录 1、概述2、案例实现1、基本功能2、代码实现3、控件应用4、案例效果4、总结1、概述 在开发用户界面时,TextBox 是最常见的输入控件之一。为了提升用户体验,我们经常需要为 TextBox 添加一些额外的功能,例如显示提示文本(水印)和设置圆角边框。本文将详细介绍如何…

使用枚举实现单例模式,不会反序列化破坏攻击,不会被反射破坏攻击。(附带枚举单例的简单实现)

原因分析 1.反序列化方法 ① jdk8中的Enum源码中对反序列化方法进行重写&#xff0c;抛出异常。 java.lang.Enum#readObject方法截图如下 ②java.io.ObjectInputStream#readObject 方法中的 readEnum 方法处理了枚举类型的反序列化&#xff0c;从而确保了枚举的单例特性。 …

Linux下的守护程序

启动流程 嵌入式设备下Linux的内核系统启动的流程并不复杂&#xff0c;从最早的父进程init开始&#xff0c;为创建各种服务进程&#xff1a;系统会从 inittab 文件中&#xff0c;读取每一行作为执行命令&#x1f447; # Note: BusyBox init doesnt support runlevels. The r…

2024第十六届蓝桥杯模拟赛(第二期)-Python

# 2024第十六届蓝桥杯模拟赛&#xff08;第二期&#xff09;-Python题解 # 自己改注释# -----------------------1------------------------ # def prime(x): # if x < 2: # return 0 # for i in range(2, int(x ** 0.5) 1): # if x % i 0: # …

MongoDB-副本集

一、什么是 MongoDB 副本集&#xff1f; 1.副本集的定义 MongoDB 的副本集&#xff08;Replica Set&#xff09;是一组 MongoDB 服务器实例&#xff0c;它们存储同一数据集的副本&#xff0c;确保数据的高可用性和可靠性。副本集中的每个节点都有相同的数据副本&#xff0c;但…

《数据结构》(408代码题)

2009 单链表&#xff08;双指针&#xff09; 分析&#xff1a;首先呢&#xff0c;给我们的数据结构是一个带有表头结点的单链表&#xff0c;也不允许我们改变链表的结构。链表的长度不是直接给出的啊&#xff0c;所以这个倒数也很棘手。那我们该如何解决这个“k”呢&#xff0c…

6.1 初探MapReduce

MapReduce是一种分布式计算框架&#xff0c;用于处理大规模数据集。其核心思想是“分而治之”&#xff0c;通过Map阶段将任务分解为多个简单任务并行处理&#xff0c;然后在Reduce阶段汇总结果。MapReduce编程模型包括Map和Reduce两个阶段&#xff0c;数据来源和结果存储通常在…

Cad c#.net 一键修改标注dimension中的文本内容

本例为给标注加前缀&#xff0c;也可定制其他形式&#xff0c;效果如下&#xff1a; public class Demo{[CommandMethod("xx")]//public void Dim(){Document doc Application.DocumentManager.MdiActiveDocument;Database db doc.Database;Editor ed doc.Editor;…

Scala的隐式类

package hfd //隐式类 //任务&#xff1a;给之前的BaseUser添加新的功能&#xff0c;但是不要直接去改代码 //思路&#xff1a;把BaseUser通过隐式转换&#xff0c;改成一个新类型&#xff0c;而这个新类型中有这新的方法 //implicit class一个隐式转换函数类 //作用&#xff1…

旅游系统旅游小程序PHP+Uniapp

旅游门票预订系统&#xff0c;支持景点门票、导游产品便捷预订、美食打卡、景点分享、旅游笔记分享等综合系统 更新日志 V1.3.0 1、修复富文本标签 2、新增景点入驻【高级版本】3、新增门票核销【高级版】4、新增门票端口【高级版】