c++ 赋值运算符函数

2023-11-07

题目:如下为类型CMyString 的声明,请为该类型添加赋值运算符

class CMyString{
 public:
    CMyString(char* pData = nullptr);
    CMyString(const CMyString& str);
    ~CMyString(void);
private:
    char* m_pData;
};

普通写法:

CMyString &CMyString::operator=(const CMyString &str) // 如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,造成浪费,在赋值运算函数内不会改变传入的实例的状态,所以用const 关键字
{
     if (this == &str) {
         return *this; //如果不判断会导致严重内存泄漏的问题,自身实例也会被析构
     }
    delete[] m_pData;
     m_pData = nullptr;

     m_pData = new char[strlen(str.m_pData) + 1];
     strcpy(m_pData, str.m_pData);
  
    return *this; //只有返回一个引用,才会允许连续赋值
}

 可能存在的问题,如果在 new char 抛出异常,m_pData 将是一个空指针,这样非常容易导致程序崩溃,违背 异常安全性原则

安全写法:

CMyString &CMyString::operator=(const CMyString &str)
{
    /*
     if (this == &str) {
         return *this;
     }
    delete[] m_pData;
     m_pData = nullptr;

     m_pData = new char[strlen(str.m_pData) + 1];
     strcpy(m_pData, str.m_pData);
  */
    if (this != &str) {
        CMyString strTemp(str);

        char *pTemp = strTemp.m_pData;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;
    }
    return *this;
}

在这个函数中,我们先创建一个临时实例 str Temp,接着把 strTemp.m_pData 和实例自身的 mpData 进行交换。由于strTemp 是一个局部变量,但程序运行到 记 的外面时也就出了该变量的作用域,就会自动调用 strTemp的析构函数,把strTemp.m pData所指向的内存释放掉。由于
str Temp.m pData 指向的内存就是实例之前 m pData 的内存,这就相当于自动调用析构函数释放实例的内存。

完整代码:

#include <QCoreApplication>
#include <cstring>
#include <iostream>
#include <ostream>

class CMyString
{
public:
    CMyString(char *pData = nullptr);
    CMyString(const CMyString &str);
    ~CMyString(void);
    CMyString &operator=(const CMyString &str);
    friend std::ostream &operator<<(std::ostream &os, const CMyString &str);

private:
    char *m_pData;
};

CMyString &CMyString::operator=(const CMyString &str)
{
    /*
     if (this == &str) {
         return *this;
     }
    delete[] m_pData;
     m_pData = nullptr;

     m_pData = new char[strlen(str.m_pData) + 1];
     strcpy(m_pData, str.m_pData);
  */
    if (this != &str) {
        CMyString strTemp(str);

        char *pTemp = strTemp.m_pData;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;
    }
    return *this;
}

CMyString::CMyString(char *pData)
{
    if (pData == nullptr) {
        m_pData = new char(1);
        m_pData[0] = '\0';
    } else {
        int len = strlen(pData) + 1;
        m_pData = new char(len);
        m_pData = pData;
    }
}

CMyString::~CMyString(void)
{
    delete m_pData;
    m_pData = nullptr;
}

CMyString::CMyString(const CMyString &str)
{
    int len = strlen(str.m_pData) + 1;
    m_pData = new char(len);
    m_pData = str.m_pData;
}

std::ostream &operator<<(std::ostream &os, const CMyString &str)
{
    os << str.m_pData;
    return os;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char *c = "string";
    CMyString b(c);
    CMyString d = b;

    std::cout << "b = " << b << "     "
              << "d =" << d << std::endl;
    return a.exec();
}

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

c++ 赋值运算符函数 的相关文章

随机推荐

  • ssh简介

    常见的远程管理工具方式 RDP remote desktop protocal 协议 windows远程桌面管理 图形界面 telenet CLI界面下远程管理 几乎所有操作系统都有 内容明文传输 23 ssh CLI界面下的远程管理 几乎
  • WIFI:802.11协议帧格式

    802协议桢格式 802 11和Wi Fi技术并不是同一个东西 Wi Fi标准是802 11标准的一个子集 并且是Wi Fi联盟负责管理 802协议桢格式 协议 发布年份 日期 Op 标准频宽 实际速度 标准 实际速度 最大 半径范围 室内
  • JavaScript和php(各版本)对称加解密

    使用npm先安装crypto js npm install crypto js javascript对称加解密 import CryptoJs from crypto js method encrypt 对称加密字符串 param Stri
  • 八股文死记硬背打脸记

    背景 我们都知道 再编程领域数据结构的重要性 常见的数据结构包括 List Set Map Queue Tree Graph Stack 等 其中 List Set Map Queue 可以从广义上统称为集合类数据结构 而Java也提供了很
  • C语言中如何使用system函数

    C语言中如何使用system函数 一 system函数 c语言中的system 函数主要用于发出一个DOS命令 该函数已经收录在标准c库中 可以直接调用 使用时包含头文件
  • Rancher和K8s的关系是什么?Rancher和K8s区别对比

    Rancher和K8s的关系是什么 K8s全称为Kubernetes 它是一个开源的 用于管理云平台中多个主机上的容器化的应用 而Rancher是一个完全开源的企业级多集群Kubernetes管理平台 实现了Kubernetes集群在混合云
  • Matrikon OPC 模拟器使用教程

    一 OPC协议 OPC通信技术因其帮助大量的使用不同通信协议的下层现场设备的数据得以与上位机的应用程序进行交互的作用 成为了一种工业通信领域中一套广为流行的方案 它使得硬件供应商和软件开发商都可以专注于做自己的工作 只要双方都能提供OPC接
  • Python NLTK 自然语言处理入门与例程

    Python NLTK 自然语言处理入门与例程 在这篇文章中 我们将基于 Python 讨论自然语言处理 NLP 本教程将会使用 Python NLTK 库 NLTK 是一个当下流行的 用于自然语言处理的 Python 库 那么 NLP 到
  • jupyter notebook参数化运行python

    Updates 2019 8 14 19 53 吃饭前用这个方法实战了一下 吃完回来一看好像不太行 跑完一组参数之后 到跑下一组参数时好像没有释放之占用的 GPU 于是 notebook 上的结果 后面好几条都报错说 cuda out of
  • Linux系统Squid代理添加用户、密码认证

    安装了Squid后会有一些不明的流量和CPU占用95 以上 估计是因为没加密码 被扫描到端口后被滥用 我们给Squid代理添加用户 密码认证 1 密码用apache2自带的NCSA 先做个密码档 然后设为任何人可读 sudo touch e
  • make all、make clean、make install 等命令的来源

    在命令行输入make命令后 会查找当前目录下的Makefile文件来执行 一切都是自动运行的 有时候Makefile中有多个程序需要编译 这时可以使用 make all 来编译所有的程序 当然也可以使用 make 程序名 来单独编译某一个文
  • C - Coprime 2(质因数)

    C Coprime 2https vjudge csgrandeur cn problem AtCoder abc215 d1 先把a数组元素里面每个元素的因数求出来 再把他们的倍数标记 剩下的1到M没标记的数就是答案 include
  • 一般试卷的纸张大小是多少_【教学研究】标准化试卷是如何编制出来的?

    作为教师 日常教学工作中经常需要编制试卷 一般我们可以用Word来编制各类试卷 对于标准化试卷来说 有很多样式是统一的 在Word中 本文以Word2003为例 我们可以按以下步骤进行设置 一 试卷页面设置 标准化试卷一般都采用8K纸张 横
  • octave下实现积分/求解微分方程

    我电脑是AMD的不是Intel的 所以matlab很多功能用不了 矩阵乘法都用不了 虚拟机也没工夫折腾 找了octave来替代 首先安装 symbolic包 要求已安装好Python3的SymPy库 pkg install forge sy
  • MongoDB4.x创建数据库帐号,启用密码认证,启用外部ip访问,创建数据库,创建集合.

    创建数据库 use company 这样就创建了一个名称为company的数据库 但如果不创建集合 表 的话则不保存 创建集合 db createCollection employ salary 创建了一个employ salary表 创建
  • WPF的MVVM框架Stylet开发文档 14.6 StyletIoC 模块

    14 6 StyletIoC 模块 任何具有合理复杂性的应用程序都将包含大量 IoC 容器配置 有大量接口与实现的显式绑定 指定单例和其他 完全必要的 配置 默认方法是将所有这些配置放在您的引导加载程序中 这是有道理的 所有配置都在一个地方
  • ModuleNotFoundError: No module named ‘tensorflow.contrib‘ 关于TensorFlow2中没有contrib包的解决办法

    在学习中文实体识别的过程中 参考很多以前的ltsm crf代码 以及谷歌的开源bert代码 过程中都遇到了该问题 简单查阅可得这是因为TensorFlow2版本中删除了contrib包所导致的问题 其中有部分大佬给出的解决办法是降低版本 但
  • PHP 短信验证码验证(短信宝)

    注册的短信验证 控制器 public function save Request request echo 11 die phone input last time Cache store redis gt get register tim
  • nvdiffrec在Windows上的配置及使用

    nvdiffrec是NVIDIA研究院开源的项目 源代码地址 https github com NVlabs nvdiffrec 论文为 Extracting Triangular 3D Models Materials and Light
  • c++ 赋值运算符函数

    题目 如下为类型CMyString 的声明 请为该类型添加赋值运算符 class CMyString public CMyString char pData nullptr CMyString const CMyString str CMy