拷贝构造函数的调用方式以及相关问题【最清晰易懂】

2023-11-15

这几天一直有一个问题在我大脑里挥之不去,之前面试实习的时候也被问过,但是回答的不好:

面试官问:你知道的构造函数有哪些?

我说:无参构造函数、有参构造函数、拷贝构造函数、移动构造函数,*()&&*(关于一些函数的说明);

面试官说:其实拷贝构造函数、移动构造函数这些都可以叫有参构造函数%……&&*;

所以,现在在看到这个问题,我沉思了。究其原因,还是网上搜罗的答案太良莠不齐了,感觉很多都是自己诹的名词,随手摆上去的,有点坑了我们这些小辈了,当然,也或者我当时并没有仔细查阅资料,没有搜到正确的解释,就胡乱背了。

废话不多说,就目前来看,个人感觉我应该是整明白这些构造函数了,现在来说一说,如果大家觉得哪些地方说的不对,恳请赐教!!

01. 什么是构造函数,有什么用?

        构造函数是类中的一个特殊的类成员函数,主要用来在创建对象时初始化对象,即为对象成员变量赋初值;

【来自百度百科构造函数_百度百科 (baidu.com)

02. 常用构造函数有哪几种,写法是什么?

        常用构造函数:默认构造函数、普通构造函数、拷贝构造函数、移动构造函数

2.1   默认构造函数:

class A{
    A(){
        cout<<"我是默认构造函数\n";
    }
}

2.2   普通构造函数:

class A{
    A(int a ,int b ){
        cout<<"我是普通构造函数\n";
    }
}

2.3   拷贝构造函数:

class A{
    A(const A& tmp){
        cout<<"我是拷贝构造函数\n";
    }
}

2.4   移动构造函数:

class A{
    A(A &&c){
        cout<<"我是移动构造函数\n";
    }
}

03.什么时候调用拷贝构造函数?

调用拷贝构造函数的三种场合

1. 用一个类对象初始化另一个类对象时;

2. 当一个函数以值传递的方式传递类对象时;

3. 当一个函数返回一个局部类对象时;

class A{
    A(){
        cout<<"我是默认构造函数\n";
    };
     A(int a ,int b ){
        cout<<"我是普通构造函数\n";
    };
    A(const A& tmp){
        cout<<"我是拷贝构造函数\n";
    };
  /*
    A(A &&c){
        cout<<"我是移动构造函数\n";
    };
  */

};
void fun1(A b){
    cout<<"我是fun1\n";
}
A fun2(){
    A c;
    cout<<"我是fun2\n";
    return c;
}
int main(){
    A a;//调用默认构造函数;
    A b(1,2);//调用普通构造函数;

//调用拷贝函数的三种方式:

//用一个类对象初始化另一个类对象
    A c(b);
    A d=b;

//一个函数的参数是类对象时
    fun1(b);

// 一个函数的返回值是局部类对象时
    A e=fun2();
}

04 调用拷贝构造函数的注意事项

在上述三种方法中,第三种方法可能会出现以下情况:

1. 编译器处于ROV(return Optimization Value)状态下,不会打印拷贝信息;

2. 当类构造方法中出现移动构造函数时,不会打印拷贝信息;

针对第一种问题,是因为编译器优化的结果,通过以下方式解决:

 针对第二种问题,则是因为,当移动构造与拷贝构造一同出现时,编译器会优先执行移动构造函数,因此,不会出现拷贝构造的相关信息。这是与返回值和参数有关的。

已知 左值引用 &,右值引用 &&;

对于拷贝构造函数,参数 —— const 类 & 类名,为左值引用类型;

对于移动构造函数,参数——  类&&类名, 为右值引用类型;

而第三种方式返回的类对象为临时变量,是没有名字与地址的,属于右值类型;

所以 表面上 A e 接收的是一个类对象,是用一个类对象初始化另一个类对象,但实际上,此时调用的是移动构造函数。

题外话:关于赋值运算符“=”

        对于很多博客上提到  “赋值构造函数”,这个属实让我迷茫了一段时间,心里纳闷为什么这些都没听过,这个赋值构造函数 与 赋值运算符是什么关系?

        但实际上,写法上都是这样:

A& operator=(const A&f){
    cout<<"我是赋值函数\n"<<endl;
}

         我不知道“赋值构造函数”这个函数是不是书上有明确提过,不做评论,个人感觉提到过的各种类型的构造函数,算是对默认构造函数的重载,这个“赋值构造函数”写法上到不是重载,甚至有人说这个是浅拷贝,我就满脸黑人问号了。。。。

        总之,以上就是我个人对构造函数的总结,如果有帮助最好,如果有不对的地方,希望大家也能够给予指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

拷贝构造函数的调用方式以及相关问题【最清晰易懂】 的相关文章

  • 将 Stream 反序列化为 List 或任何其他类型

    尝试将流反序列化为List
  • Accept() 是线程安全的吗?

    我目前正在用 C 语言为我正在做的课程编写一个简单的网络服务器 我们的一项要求是实现一个线程池来使用 pthread 处理连接 我知道我将如何粗略地执行此操作 在主线程中调用accept并将文件描述符传递给freee线程 但是我的朋友建议了
  • 键盘加速器在 UWP 应用中停止工作

    我正在尝试将键盘加速器添加到 UWP 应用程序中的 CommandBar 菜单项 当应用程序启动时 这工作正常 但在我第一次打开溢出菜单后 加速器停止工作 这似乎不会发生在主要命令 菜单之外 上 只有溢出菜单内的辅助命令才会发生 此外 单击
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • 为什么这个函数指针赋值在直接赋值时有效,但在使用条件运算符时无效?

    本示例未使用 include 在 MacOS10 14 Eclipse IDE 上编译 使用 g 选项 O0 g3 Wall c fmessage length 0 假设这个变量声明 int fun int 这无法通过 std touppe
  • 访问“if”语句之外的变量

    我怎样才能使insuranceCost以外可用if陈述 if this comboBox5 Text Third Party Fire and Theft double insuranceCost 1 在 if 语句之外定义它 double
  • 找到的程序集的清单定义与程序集引用不匹配

    我试图在 C Windows 窗体应用程序 Visual Studio 2005 中运行一些单元测试 但出现以下错误 System IO FileLoadException 无法加载文件或程序集 实用程序 版本 1 2 0 200 文化 中
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • 矩阵向量变换

    我正在编写一个代码来制作软件蒙皮器 骨骼 皮肤动画 并且我正处于 优化 阶段 蒙皮器工作得很好 并且在 Core 上 1 09 毫秒内对 4900 个三角形网格与 22 个骨骼进行蒙皮Duo 2 Ghz 笔记本 我需要知道的是 1 有人可以
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 指向字节数组的指针

    由于 Misra C 的要求 我的一位同事想要使用指针声明 但我遇到了一些问题 Misra 安全关键指南 不会让我们纯粹的程序员使用指针 但会让我们对数组字节进行操作 他打算获取一个指向字节数组的指针 因此我们不会在堆栈上传递实际的数组 T
  • 无法加载文件或程序集“EntityFramework,版本=6.0.0.0”

    我究竟做错了什么 我该如何解决这个问题 我有一个包含多个项目的解决方案 它是一个 MVC NET 4 5 Web 应用程序 在调试模式下启动后调用其中一个项目时 出现此错误 导致此错误的项目具有以下参考 两个都是版本6 0 0 0 应用程序
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • 格式化货币

    在下面的示例中 逗号是小数点分隔符 我有这个 125456 89 我想要这个 125 456 89 其他示例 23456789 89 gt 23 456 789 89 Thanks 看看这个例子 double value 12345 678
  • 纯虚函数可能没有内联定义。为什么?

    纯虚函数是那些虚函数并且具有纯说明符 0 第 10 4 条第 2 款C 03 的内容告诉我们什么是抽象类 顺便说一句 如下 注意 函数声明不能 同时提供纯说明符和定义 尾注 示例 struct C virtual void f 0 ill
  • 使用 Chrome 和 Selenium 设置 LocalStorage

    我正在尝试使用 OpenQA Selenium 和 Chrome 设置本地存储键和值 我认为这相当微不足道 但我似乎无法让它发挥作用 我对 C 很陌生 所以我可能错过了一些东西 无论如何 我有这个功能 public static void
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • MySQL引起索引失效的原因

    原创92 4 发布于2018 11 30 19 35 07 阅读数 451 收藏 展开 查看索引结构 mysql gt show index from staffs Table Non unique Key name Seq in inde
  • cmake_policy规定了cmake解析行为

    https blog csdn net gispipi article details 108275569
  • Python中字符串和列表去重方法

    本文主要为大家整理了Python中实现字符串和列表去重的常用方法 文中的示例代码讲解详细 对我们深入了解Python有一定的帮助 感兴趣的可以了解一下 字符串去重 1 直接遍历字符串的方式 1 2 3 4 5 6 7 8 coding UT
  • Redis第三讲 Redis 4.0 混合持久化与Redis数据备份策略

    RDB 和 AOF 持久化各有利弊 RDB 可能会导致一定时间内的数据丢失 而 AOF 由于文件较大则会影响 Redis 的启动速度 为了能同时使用 RDB 和 AOF 各种的优点 Redis 4 0 之后新增了混合持久化的方式 加载优先级
  • 【理论实践】指向类模板函数的指针的使用(以std::list为例)

    假设有这个一个场景 我们希望根据条件决定插入元素到list首或尾 条件判断一次 插入操作多次 例如二叉树 至少要处理左和右各一次 普通的代码很简单 每次操作时 都判断一下 简化一下是一个三元表达式 巧妙一点的 可以定义一个变量指定接口函数
  • QT学习笔记:多线程操作

    做了一个demo展示两种形式的多线程操作 第二种常用 new QThread Class Override run new Object Class moveToThread new QThread threadfirst h 第一种形式的
  • Js Jquery 关于endWith() 和startWith() 的使用

    javascript中字符串处理并没有 StartWith 和 EndWith 这俩个方法 这里说的是手动构建这俩个方法 JQuery 也是没有这俩个方法的 而是利用其丰富的选择器来达到此效果 首选javascript下着俩个函数的构建如下
  • RFC7296--Internet密钥交换协议版本2(IKEv2)

    2 8 密钥更新 rekeying IKE ESP和AH安全联盟 SA 使用的共享密钥应该只在有限的时间里保护优先的数据 这限制了整个SA的生存周期 生存周期超时的SA决不能再使用 如果有需要 可以建立新的SA 重建SA以取代过期的SA被称
  • Python 文件操作(IO)

    文章目录 前言 一 打印到屏幕 print 二 读取键盘输入 1 raw input 2 input 三 读写文件 读文件 写文件 前言 和其它编程语言一样 Python 也具有操作文件 I O 的能力 比如打开文件 读取和追加数据 插入和
  • 什么是token?

    什么是token token就是令牌 前后端进行鉴权的一种有效形式 比传统的 session 鉴权更加方便 简单来说 当用户首次登陆时 网站会给你一张 门卡 以后你可以凭借门卡直接进入 而无需再次申请 但一段时间之后门卡实效 你需要再到前台
  • 如何调用本业务模块外的服务——服务调用

    上篇已经引入 Nacos 基础组件 完成了服务注册与发现机制 可以将所有服务统一的管理配置起来 方便服务间调用 本篇将结合需求点 进行服务间调用 完成功能开发 几种服务调用方式 服务间调用常见的两种方式 RPC 与 HTTP RPC 全称
  • 一个简洁的PNG ICO转换工具 支持多分辨率的ICO生成

    一个绝美的PNG ICO转换工具 支持多分辨率的ICO生成 下载地址 http www ppsbbs tech thread 58 htm
  • Kotlin 1.2 新特性

    点击关注异步图书 置顶公众号 每天与你分享IT好书 技术干货 职场知识 在Kotlin 1 1中 团队正式发布了JavaScript目标 允许开发者将Kotlin代码编译为JS并在浏览器中运行 在Kotlin 1 2中 团队增加了在JVM和
  • Intellij Idea怎么撤销,反撤销

    Intellij IDEA中 1 Ctrl z是撤销快捷键 2 反撤销快捷键为 Ctrl Shift Z
  • React 配置路由

    1 在 index 中引入 App 文件 index 是入口文件 并且在 index 中引入样式文件等等 把 App 挂载到 DOM 元素上 2 在 App 组件中
  • 3 亿岗位将被 AI 取代?巴比特深度采访业界后,“失业潮”真相有些出人意料……...

    图片来源 由无界 AI工具生成 人工智能技术的发展正迎来奇点 尤其是今年以来 ChatGPT 和 AIGC 的迅猛势头让无数人猝不及防 真真切切地对各行各业现有的工作岗位产生冲击 近日 蓝色光标全面停止创意设计 方案撰写 文案撰写 短期雇员
  • (简单成功版本)Mysql配置my.ini文件

    目录 一 背景 二 删除原有的mysql服务 三 初始化mysql 四 自行添加my ini文件 五 新建mysql服务 六 启动mysql服务 七 设置数据库密码 7 1 登录mysql数据库 7 2 修改root用户密码 八 配置my
  • Xcode编译报错不提示

    M1 Xcode Version 12 5 1 12E507 编译项目之后提示 Build Failed 但是并不报 小红点 不指示是哪个文件报错 不知道去哪里找报错文件了 Xocode 工具栏上有这个按钮 选择之后点击某次编译 如果有错误
  • DOTA目标检测数据集

    Dota开源目标检测数据集 DOTA v1 5包含16个类别中的40万个带注释的对象实例 这是DOTA v1 0的更新版本 它们都使用相同的航拍图像 但是DOTA v1 5修改并更新了对象的注释 其中许多在DOTA v1 0中丢失的10像素
  • 拷贝构造函数的调用方式以及相关问题【最清晰易懂】

    这几天一直有一个问题在我大脑里挥之不去 之前面试实习的时候也被问过 但是回答的不好 面试官问 你知道的构造函数有哪些 我说 无参构造函数 有参构造函数 拷贝构造函数 移动构造函数 关于一些函数的说明 面试官说 其实拷贝构造函数 移动构造函数