类模板以及赋值运算符重载、拷贝构造函数

2023-11-10

编译器默认的拷贝构造函数,是发生的浅拷贝,像指针的赋值就会让指针指向同一个地址空间,析构时就会对同一个地址空间释放两次,就会造成程序崩溃.
自定义在模板内的拷贝构造函数:

Queue(const Queue<T> &src)//类对象的拷贝构造函数
    {
        //Queue();
        _pfirst = _prear = NULL;
        QueueItem*p =src._pfirst;
        while (p != NULL)
        {
            addQue(p->_data);
            p = p->_pnext;
        }
    }

上述拷贝构造函数仅仅支持同种类型的对象之间的拷贝构造,对于不同类型的对象之间的拷贝构造就需要建立如下模板(但是必须在定义友元类):

private中需要先定义如下:
template<typename E>
friend class Queue;
template<typename E>
    Queue(const Queue<E>&src)//自定义拷贝构造函数的模板,Queue<E>为新类型,必须先声明Queue<E>类类型为此类型的友元类型,此模板不能替代上述同类型的拷贝构造
    {
        cout << "const Queue<E>& 模板" << endl;
        _pfirst = _prear = NULL;
        Queue<E>::QueueItem*p = src._pfirst;//必须加Queue<E>这个作用域,否则指针的类型不一样,会出现错误。
        while (p != NULL)
        {
            addQue(p->_data);
            p = p->_pnext;
        }
    }

此模板在模板外定义:

//不同类型对象的拷贝构造函数的模板外定义
template<typename T>
template<typename E>
Queue<T>::Queue(const Queue<E> &src)
{
    Queue<E>::QueueItem*p = src._pfirst;
    while (p != NULL)
    {
        addQue(p->_data);
        p = p->_pnext;
    }
}

此支持不同类型对象之间的拷贝构造函数不能替代同种类型对象的的拷贝构造函数。
赋值运算符同样需要自定义,否则就会出现和拷贝构造相同的问题,自定义的相同类型的对象之间的赋值运算符重载函数:

void operator=(const Queue<T> &src)//自定义的赋值运算符的重载函数,避免了编译器默认的浅拷贝,造成的内存泄漏等问题
    {
        cout << "operator Queue<T> &src" << endl;
        if (this == &src)
        {
            return;
        }
        if (_pfirst != NULL)
        {
            while (_pfirst != _prear)
            {
                QueueItem*tmp = _pfirst->_pnext;
                delete _pfirst;
                _pfirst = tmp;
            }
        }
        delete _pfirst;
        _pfirst = _prear = NULL;//必须将头尾指针指向NULL,否则就会从_pfirst的位置向后添加元素,而_pfirst的位置确是已经释放的随机值

        QueueItem*p = src._pfirst;
        while (p != NULL)
        {
            addQue(p->_data);
            p = p->_pnext;
        }
    }

不同类型对象之间的赋值运算符的重载函数模板:

template<typename E>
    void operator=(const Queue<E> &src)//不同类型对象之间的赋值运算
    {
        cout << "operator Queue<T> &src模板" << endl;

        if (_pfirst != NULL)
        {
            while (_pfirst != _prear)
            {
                QueueItem*tmp = _pfirst->_pnext;
                delete _pfirst;
                _pfirst = tmp;
            }
        }
        delete _pfirst;
        _pfirst = _prear = NULL;

        Queue<E>::QueueItem*p = src._pfirst;
        while (p != NULL)
        {
            addQue(p->_data);
            p = p->_pnext;
        }
    }

在没有给定此模板时,此句int_queue = double_queue会先调用不同类型对象直接的拷贝构造函数先生成同种类型得临时对象,再调用同种类型的赋值运算符的重载函数赋值成功,当定义了此 模板就直接实例化此模板一次就完成赋值。

主函数:


int main()
{

    Queue<int> int_queue;
    int_queue.addQue(10);
    int_queue.addQue(20);

    Queue<double> double_queue = Queue<double>();
    double_queue.addQue(30.5);

    Queue<int> int1_queue(int_queue);//相同类型对象之间的拷贝构造,需要自定义拷贝构造函数,否则编译器默认的造成浅拷贝(指针的赋值)导致出错
    int1_queue.addQue(40);

    Queue<int> int2_queue(double_queue);//不同类型对象之间的拷贝构造,编译器不会产生,需要自定义。
    cout <<"int_queue------------------------------------------" << endl;
    int_queue.show();
    cout << "int1_queue----------------------------------------" << endl;
    int1_queue.show();
    cout << "double_queue--------------------------------------" << endl;
    double_queue.show();
    cout << "int2_queue----------------------------------------" << endl;
    int2_queue.show();
    cout << "赋值运算符的重载函数---------------------------------------------" << endl;
    //int_queue = int1_queue;
    //int_queue = Queue<int>(int1_queue);

    //int_queue = double_queue;在没有给定不同类型的对象之间的赋值运算符的重载函数时,编译器会先调用不同类型对象的拷贝构造函数
    //将double类型的对象构造成Int类型的临时对象,在调用相同类型对象之间的赋值运算符赋值给int_queue
    int_queue = Queue<double>(double_queue);
    int_queue.show();
    return 0;
}

运行结果:
Visual Leak Detector Version 2.4RC2 installed.
const Queue& 模板
int_queue——————————————
10 20
int1_queue—————————————-
10 20 40
double_queue————————————–
30.5
int2_queue—————————————-
30
赋值运算符的重载函数———————————————
operator Queue &src模板
30
No memory leaks detected.
Visual Leak Detector is now exiting.
请按任意键继续…

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

类模板以及赋值运算符重载、拷贝构造函数 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • 使用可变参数包类型扩展的 C++ 函数调用者包装器

    我绑定了一些 API 并且绑定了一些函数签名 如下所示 static bool WrapperFunction JSContext cx unsigned argc JS Value vp 我尝试将对象和函数包装在 SpiderMonkey
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp

随机推荐

  • 机械技术在橡胶工业中的应用概述 机械外文文献翻译

    原文 Mechanical Technology in the rubber industry outlined in the application In the development of human society is the m
  • 性能测试如何做?从0到1性能测试实战(手把手教)

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 各种排序的比较和使用场景分析

    冒泡排序 冒泡排序重复地走访过要排序的数列 一次比较两个元素 如果他们的顺序错误就把他们交换过来 走访数列的工作是重复地进行直到没有再需要交换 也就是说排序完成 规模比较小的时候应用冒泡排序 主要应用于教学 选择排序 只会移动N次 选择排序
  • 最大熵模型简介[例子+推导+GIS求解…

    这篇文章是结合论文http www cqvip com Main Detail aspx id 7707219对博文 http www cnblogs com hexinuaa p 3353479 html加入自己的理解做了简化重写 另外本
  • 使用jQuery实现显示文字气球的提示

    使用jQuery实现显示文字气球的提示 本文由 arthinking 发表于884 天前 Javascript 暂无评论 被围观 3 115 views 为了使页面效果更绚丽 可以使用文字气球的提示功能 在jQuery中 可以使用简单的几条
  • Unity Mecanim动画系统 之 解决模型有些动画播放后发生的位置、方向偏转 (根骨骼动画)的问题

    Unity Mecanim动画系统 之 解决模型有些动画播放后发生的位置 方向偏转 根骨骼动画 的问题 目录 Unity Mecanim动画系统 之 解决模型有些动画播放后发生的位置 方向偏转 的问题 一 简单介绍 二 实现原理 三 效果预
  • ebay运营思路

    Ebay是一个老牌的跨境电商 目前仍然是稳坐全球前列的平台 也是强手如云的地方 虽然相对于亚马逊他显得没有那么 卷 要在这片市场中抢占一番天地 首先一定要学会一些高效的运营技巧 今天就来分享一些Ebay运营技巧 帮助你更快更好的打造一个高质
  • STM32四旋翼设计——1.系统架构

    一 前言 历时一年半 终于将STM32四旋翼调通 2023 4 9顺利起飞 现在想将这个设计过程都记录下来 包括板子的设计方案 板卡结构设计 板卡原理图 PCB 各模块调试的过程 但大部分只涉及硬件 软件部分后面看情况整理 因为程序部分我也
  • 用vite 新建vue3项目

    1 component里的HelloWorld vue 是组件 2 总的vue App vue 3 index css 写的App vue的css 不是组建的vue 为什么呢 4 main js 几个import来源 HelloWorld
  • 694 不同岛屿的数量

    题目描述 给定一个非空 01 二维数组表示的网格 一个岛屿由四连通 上 下 左 右四个方向 的 1 组成 你可以认为网格的四周被海水包围 请你计算这个网格中共有多少个形状不同的岛屿 两个岛屿被认为是相同的 当且仅当一个岛屿可以通过平移变换
  • IOS本地推送 学习手记

    iOS上有两种消息通知 一种是本地消息 Local Notification 一种是远程消息 Push Notification 也叫Remote Notification 设计这两种通知的目的都是为了提醒用户 现在有些什么新鲜的事情发生了
  • JavaWeb学习笔记 ---- HTML

    web概念概述 软件架构 1 C S Client Server 客户端 服务器端 在用户本地有一个客户端程序 在远程有一个服务器端程序 优点 用户体验好 缺点 开发 安装 部署 维护 麻烦 2 B S Browser Server 浏览器
  • Python机器学习从零开始(一)序章

    目录 前言 写在前面 1 什么是机器学习 1 1 监督学习 1 2无监督学习 2 Python中的机器学习 3 必须环境安装 Anacodna安装 总结 前言 每一次变革都由技术驱动 纵观人类历史 上古时代 人类从采集狩猎社会 进化为农业社
  • node.js学习笔记--定义GET和POST路由

    const http require http const queryString require querystring const server http createServer req res gt const url req ur
  • csapp 第一章 计算机系统漫游

    计算机系统由硬件和系统软件组成 共同工作来运行应用程序 include
  • Java基础+进阶

    本文适合Java入门和复习回顾 高级篇请参考导航里的面试题 导航 黑马Java笔记 踩坑汇总 Java基础 JavaWeb SSM SpringBoot 瑞吉外卖 SpringCloud 黑马旅游 谷粒商城 学成在线 牛客面试题 目录 一
  • 实现小说分页article

    翻页过程 代码实现 css部分 margin 0 padding 0 box sizing border box wrapper height 100vh overflow hidden margin 0 16px article colu
  • 【每日知识】React学习笔记

    一 React特点 1 声明式编程 2 组件化开发 3 多平台适配 二 React开发依赖 1 React 包含react所必须的核心代码 2 react dom react渲染在不同平台所需的核心代码 3 babel 将jsx转换成rea
  • 【ChatGPT实战】9.使用ChatGPT-+-Midjourney-帮忙做了个App

    在当今数字化的时代 手机App已经成为人们生活的重要组成部分 开发一个优秀的手机App需要付出大量的时间和精力 特别是在设计和开发阶段 但是现在我们可以借助工具和技术来协助自己简化这个过程 在这篇教程中 我将介绍如何使用ChatGPT和Mi
  • 类模板以及赋值运算符重载、拷贝构造函数

    编译器默认的拷贝构造函数 是发生的浅拷贝 像指针的赋值就会让指针指向同一个地址空间 析构时就会对同一个地址空间释放两次 就会造成程序崩溃 自定义在模板内的拷贝构造函数 Queue const Queue