c++ 理解 关于构造函数和析构函数

2023-11-06

构造函数和析构函数

1 首先,C++有拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符和析构函数

构造函数可以先分为:默认构造函数和拷贝构造函数,如果我们在代码中不显示的自己声明构造函数的话,c++的编译器会为我们默认生成默认构造函数和拷贝构造函数

1 针对默认构造函数

默认构造函数可以使用两种方式实现:1 赋值,2 列表初始化

2 针对拷贝构造函数

拷贝构造函数分为深拷贝和浅拷贝
浅拷贝是只是复制内容,原对象的操作会影响现有的实例化的对象
深拷贝不仅仅复制内容,是复制内容并且拷贝到另一份新的空间,两个实例化的对象不会互相干扰互相影响
c++编译器在我们没有显示的实现拷贝构造函数的时候默认是浅拷贝
浅拷贝容易有bug,如果存在引用值或者指针的时候,不重载拷贝构造函数和拷贝赋值运算符的话,在对象销毁的时候,析构函数会多次释放指向的对象,导致错误。

3 关于析构函数

析构函数没有函数返回类型和形参,析构函数可以是虚函数,但是析构函数是不允许重载的,因为虚构函数没有返回值类型和形参。子类的虚构函数可以继承基类的虚构函数并进行重写

关于什么时候需要自己实现拷贝构造函数和拷贝赋值运算符

一般来说我们会声明默认构造函数和析构函数,c++编译器目前会默认的给我们定义合成拷贝构造函数和合并赋值运算符。合成拷贝构造函数只是默认的复制类的成员变量,如果出现指针,引用等类型时,因为没有显示的去重载拷贝构造和复制运算符,在析构函数时,指针会指向同一对象,然后该对象已经被销毁了,再次销毁会出现意向不到的错误。
因此,我们可以根据是否在析构函数体内部需要对指针或者引用做出释放等操作时,去决定是否需要重载拷贝构造函数和复制运算符。反之亦然。
如果需要重载拷贝沟道函数,那么也要重载复制运算符。反之亦然。

class HasPtr {
public:
    HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) { }
    HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) { }  //拷贝的是指针指向的对象
    HasPtr& operator=(const HasPtr& rhs_hp) {
        if(this != &rhs_hp) {
            std::string *temp_ps = new std::string(*rhs_hp.ps);  //先拷贝到一个临时指针中,但是指针分配的动态内存不是临时的。
            delete ps;     // delete 时不用加 *
            ps = temp_ps;  // 让 ps 指向分配的动态内存。
            i = rhs_hp.i;
        } 
        return *this;
    }
    ~HasPtr() { delete ps; }
private:
    std::string *ps;
    int i;
}

关于default和delete

default :只允许c++编译器能够生成默认的构造函数声明加上default,意思是这个变为内联函数并且由c++编译器默认生成。
我们的拷贝构造函数 拷贝赋值运算符 默认构造函数 析构函数均可以使用default
如果在类内使用 =default,合成的函数将隐式地声明为内联函数。如果不希望合成内联函数,则应该在类外定义处使用 =default
只能对默认构造函数或拷贝构造成员这些具有合成版本的函数使用 =default

delete:通过delete声明告诉我们,这个函数不能够被外界对象所使用
删除的函数的性质:虽然声明了它们,但是不能以任何方式使用它们。
定义为删除的函数的方式:在参数列表后加 =delete;
在智能指针shared_ptr实现的时候是私有化构造函数和赋值运算符,也可以通过delete声明
Student(const Student&) = delete;//阻止拷贝
=delete 只能出现在函数第一次声明的时候,并且可以对任何函数指定 =delete

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

c++ 理解 关于构造函数和析构函数 的相关文章

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • C#强制杀进程

    通过cmd命令实现 using System using System Collections Generic using System Linq using System Text using System Threading Tasks
  • 小波矩特征提取matlab代码

    这是我上研究生时写的小波矩特征提取代码 新归一化方法小波矩特征提取 F imread a1 bmp F im2bw F F imresize F 128 128 求取最上点for i 1 128 for j 1 128 if F i j 1
  • AVPlayer 播放在线视频和本地文件的设置区别

    http blog csdn net u012671808 article details 30500595 comments
  • 动态文件版通讯录及C语言中的文件的读写操作

    上一期我们编写了一个C语言版本的简易通讯录 但是我们的之前的通讯录是没有记忆功能的 也就是说 一旦关闭了程序我们存储在里面的数据也就消失了 那么今天我们就来实现一个附带数据储存的通讯录 在此之前 我们先来了解一下C语言中文件的读写函数 1
  • QT-通过控件ObjectName获取控制

    QT 通过控件ObjectName获取控制 示例 1 说明解释 示例 1 说明解释 代码如下 QString strObjectName QString lineEditDev5IP QLineEdit pLineEdit this gt
  • KVM中的ballooning详解

    KVM中的ballooning详解 1 Ballooning简介 通常来说 要改变客户机占用的宿主机内存 是要先关闭客户机 修改启动时的内存配置 然后重启客户机才能实现 而内存的ballooning 气球 技术可以在客户机运行时动态地调整它
  • kibana数据导入导出_怎么实现kibana的数据导入导出

    匿名用户 1级 2016 10 19 回答 logstash好说 client只需要在代码逻辑改下redis地址就可以了 logstash server直接docker pull镜像就可以了 elasticsearch需要我们自己写脚本迁移
  • 机器翻译 深度学习预处理实战(中英文互译)一

    深度学习预处理实战 中英文互译 文章目录 深度学习预处理实战 中英文互译 前言 一 获取中英互译的数据集 二 具体步骤 1 首先引入相关库 2 中英文预处理 3 主函数运行 前言 基于深度学习的机器翻译学习分为三步 1 解决自动将一种自然语
  • python获取指定时间段内特定规律的日期列表

    前言 写小程序时 遇到个需要自定义回归时间的场景 下面是实现的效果图 于我需求而言 我只需要用到fixed interval weekly per month三个方法返回的回归间隔列表就行 最后的这个make date from list方
  • 开源软件选型分析标准【转载】

    http wenku baidu com view 0f4acf88cc22bcd126ff0ca2 html re view 1 标准和目标 1 1前言目前开源的网管软件众多 时间关系只能通过网络上的资料介绍和其他用户的体验进行评估 对于
  • ROI Pooling层详解

    ROI Pooling层详解 原文链接 https blog deepsense ai region of interest pooling explained 目标检测typical architecture 通常可以分为两个阶段 1 r
  • NO.15 不得不说的以太坊跟ICO

    随着以太坊的出现 区块链进入了2 0时代 以太坊是个太神奇的东西 没有天才的想法 高超的技术以及黑客的精神是无法如此成功的 它实现了区块链项目的快速开发 快速实施 以太坊这个开发平台本身发行了一种币叫做以太币 ETH 使用此平台开发出来的应
  • APS系统介绍

    APS系统介绍 前言 听说新工作将是做APS系统 之前没接触过 所以查找了一些资料 整理学习记录于此 本文打算从以下几个方面来阐述 APS的概念 前提条件 怎么实现 优化算法 简单示例 APS概念 APS Advanced Planning
  • el-table表单实现点击编辑按钮对内容进行编辑

    el table表单实现点击编辑按钮对内容进行编辑 话不多说 先上效果图 这里我将按钮绑定了dialog对话框 避免直接在原有表行之间进行修改 因为后台管理系统多是响应式布局 使用dialog对话框可以更直观的让用户对内容进行编辑 而对于在
  • 【服务计算】docker实践报告

    docker实践报告 环境说明 准备docker环境 运行第一个容器 Docker基本操作 MySQL与容器化 拉取MySQL镜像 构建docker镜像 MySQL容器使用 Docker compose与多容器应用自动化部署 docker网
  • SpringBoot运行源码分析:Spring应用上下文刷新,java主流框架面试题

    protected void refresh ApplicationContext applicationContext Assert isInstanceOf AbstractApplicationContext class applic
  • 【eNSP】单臂路由+静态路由配置练习

    单臂路由 静态路由配置练习 单臂路由 又名子接口 实际上是一个逻辑接口 并不存在真正物理上的子接口 采用单臂路由 即在路由器上设置多个逻辑子接口 每个子接口都可以单独设置一个IP地址 对应于一个VLAN 由于物理路由接口只有一个 各子接口的
  • Flutter 实体类转String,String转实体类

    实体类转String方式 引用需要转换的包 import dart convert 转换方法 String jsonStr jsonEncode myInfosBeans String转实体类 引用转换包 import dart conve
  • render 怎么使用v-if

    在Vue中使用render函数 有些时候我们需要判断这个元素是否需要渲染 在正常的DOM结构中可以直接使用v if 但是 render函数中有些时候是无法使用v if 来进行判断 这时我们可以使用if 来判断是否添加该元素 render h
  • c++ 理解 关于构造函数和析构函数

    构造函数和析构函数 1 首先 C 有拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符和析构函数 构造函数可以先分为 默认构造函数和拷贝构造函数 如果我们在代码中不显示的自己声明构造函数的话 c 的编译器会为我们默认生成默认构造函数