返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++如何实现MyString
  • 442
分享到

C++如何实现MyString

2023-06-29 05:06:43 442人浏览 独家记忆
摘要

这篇文章主要介绍了c++如何实现MyString,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。MyString的构造、析构、拷贝构造、赋值运算class Strin

这篇文章主要介绍了c++如何实现MyString,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

MyString的构造、析构、拷贝构造、赋值运算

class String{char* str;public:String(const char* p = NULL) :str(NULL){if (p != NULL){str = new char[strlen(p) + 1];//strlen()计算至'\0'截至的字符数strcpy(str, p);}else{str = new char[1]; //额外提供一个空间*str = '\0';}}~String(){if (str != NULL){delete[] str;}str = NULL;}//ostream& operator<<(const String* const this, ostream &out)ostream& operator<<(ostream& out)const //重载插入操作符{if (str != NULL){out << str;}return out;}String(const String& s):str(NULL){//str = s.str; 浅拷贝 是同一个空间,会造成一个空间释放两次//深拷贝str = new char[strlen(s.str)+1];strcpy(str, s.str);}String& operator=(const String& s){if(this != &s){delete[]str;str = new char[strlen(s.str)+1]strcpy(str,s.str);}return *this;}};ostream& operator<<(ostream& out, const String& s){s << out;//s.operator<<(cout);//operator<<(&s1,cout);return out;}int main(){String s1("123");s1 << cout;//s1.operator<<(cout);//operator<<(&s1,cout);cout << s1 << endl;//operator<<(cout, s1);}

前面之所以对空指针构建对象提供一个空间的原因:使其在赋值重载中只有指向堆区一种情况进行处理

C++如何实现MyString

通过此方式进行等号运算符重载,然后调动拷贝构造对s2进行重写构造

C++如何实现MyString

输出流重写

class String{char* str;public:String(const char* p = NULL) :str(NULL){if (p != NULL){str = new char[strlen(p) + 1];strcpy(str, p);}else{str = new char[1]; //额外提供一个空间*str = '\0';}}~String(){if (str != NULL){delete[] str;}str = NULL;}//ostream& operator<<(const String* const this, ostream &out)ostream& operator<<(ostream& out)const //重载插入操作符{if (str != NULL){out << str;}return out;}};int main(){String s1("123");s1 << cout;//s1.operator<<(cout);//operator<<(&s1,cout);}

在这里通过改写前的代码 operator<<(&s1,cout); 不难看出,将cout初始化out,随后将this.str输出至out

ostream& operator<<(ostream& out)const
此处只能使用引用,因为cout在ostream类中进行转移,该类将拷贝构造函数定义为保护访问属性,无法使用cout初始化out,继而只能使用引用;同样若我们不想使用实参去初始化形参,可以将拷贝构造函数定义为私有或保护类型

若希望输出符合cout << s1 << endl;此种形式,需要再写一个全局函数

class String{char* str;public:String(const char* p = NULL) :str(NULL){if (p != NULL){str = new char[strlen(p) + 1];strcpy(str, p);}else{str = new char[1]; //额外提供一个空间*str = '\0';}}~String(){if (str != NULL){delete[] str;}str = NULL;}//ostream& operator<<(const String* const this, ostream &out)ostream& operator<<(ostream& out)const //重载插入操作符{if (str != NULL){out << str;}return out;}};ostream& operator<<(ostream& out, const String& s){s << out;//s.operator<<(cout);//operator<<(&s1,cout);return out;}int main(){String s1("123");s1 << cout;//s1.operator<<(cout);//operator<<(&s1,cout);cout << s1 << endl;//operator<<(cout, s1);}

通过此种形式进行翻转,继而达到符合 cout << s1 << endl; 的形式

MyString加号运算符重载

int main(){String s1("123");String s2("456");String s3;s3 = s1 + s2;S3 = s1 + "789";s3 = "789" + s1;}

分别写三个加号运算符重载,来对应上面的三个情况(类+类、类+字符串、字符串+类)

String operator+(const String& s)const{char *p = new char(strlen(this->str) + strlen(s.str) + 1);strcpy(p, this->str);strcat(p, s.str);return String(p);}

第一个为成员函数,但是存在内存泄漏,需要进行下面的步骤

C++如何实现MyString

在私有成员变量中,创建一个新的构造函数,直接将p给到str,而没有创建新的空间;并且在加号运算符重载进行修改使其调用私有的构造函数

private:String(char*p,int)//两个参数与公有构造区分{str = p;}public:String operator+(const String& s)const{char *p = new char(strlen(this->str) + strlen(s.str) + 1);strcpy(p, this->str);strcat(p, s.str);return String(p,1);}

这样就解决了原本内存泄漏的问题
接下来完成剩余两个等号运算符重载

String operator+(const char* s)const{char* p = new char(strlen(this->str) + strlen(s) + 1);strcpy(p, this->str);strcat(p, s);return String(p, 1);//return *this + String(s)//上面的方式更方便,但是会构造两个临时对象}

此处需要写在类外,并且需要类内添加友元函数

friend String operator+(const char* t, const String s);

String operator+(const char* t, const String s){char* p = new char(strlen(s.str) + strlen(t) + 1);strcpy(p, s.str);strcat(p, t);return String(p, 1);//return String(p) + s; 与上面同理,并且不需要友元函数}

讨论一个衍生问题

class String{private:char* str;public:String(const char* p = NULL) :str(NULL){if (p != NULL){str = new char[strlen(p) + 1];strcpy(str, p);}else{str = new char[1]; //额外提供一个空间*str = '\0';}}~String(){if (str != NULL){delete[] str;}str = NULL;}String(const String& s){//str = s.str; 浅拷贝 是同一个空间,会造成一个空间释放两次//深拷贝str = new char[strlen(s.str)];strcpy(str, s.str);}String& operator=(const String& s){if (this != &s){delete[]str;str = new char[strlen(s.str)];strcpy(str, s.str);}return *this;}};String fun(){String s2("456");return s2;}int main(){String s1;s1 = fun();return 0;}

讨论此程序执行的过程总共创建了多少个对象:

C++如何实现MyString

主函数运行首先开辟main函数栈帧,创建s1对象,默认构造只有大小为一的空间存放“\0”;之后执行fun()函数,分配fun栈帧,然后创建s2对象,创建一个堆区,str指向堆区空间;并且将按值返回,需要构建一个临时对象(将亡值);

将亡值概念:表达式过程中所产生的不具有名字的一个实体,叫做将亡值;将亡值的生存期仅在表达式的调用过程中,表达式调用结束,将亡值就会结束

构建临时对象调用拷贝构造,fun函数结束,s2生存期结束,调动析构函数;首先释放s2调用资源,再归还s2空间;回到主函数,把将亡值赋值给s1调用赋值语句,接着调用将亡值的析构函数进行释放

这个过程中总共创建了三个对象,分别是s1、s2、将亡值对象

那么如果我们对fun以引用进行返回

String& fun(){String s2("456");return s2;}int main(){String s1;s1 = fun();return 0;}

当以引用返回,就不会返回一个s2的备份,从引用底层来看会返回s2的地址;这样会从一个已死亡对象来获取数据,继而会得到随机值

C++如何实现MyString

感谢你能够认真阅读完这篇文章,希望小编分享的“C++如何实现MyString”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网其他教程频道,更多相关知识等着你来学习!

--结束END--

本文标题: C++如何实现MyString

本文链接: https://lsjlt.com/news/322793.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++如何实现MyString
    这篇文章主要介绍了C++如何实现MyString,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。MyString的构造、析构、拷贝构造、赋值运算class Strin...
    99+
    2023-06-29
  • C++实现MyString的示例代码
    MyString的构造、析构、拷贝构造、赋值运算 class String { char* str; public: String(const char* p = NULL) :...
    99+
    2024-04-02
  • 如何实现 C/C++ 与 Python
    属于混合编程的问题。较全面的介绍一下,不仅限于题主提出的问题。以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格) 本文分4个部分 1. C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实...
    99+
    2023-01-31
    如何实现 Python
  • C# 如何实现Token
    目录什么是JWT基于session认证所显露的问题基于token的鉴权机制JWT的构成C# MVC实现token什么是JWT JWT:Json web token (JWT), 是...
    99+
    2024-04-02
  • C++如何实现LeetCode
    这篇文章给大家分享的是有关C++如何实现LeetCode的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。[LeetCode] Reverse Linked List 倒置链表Reverse a singly lin...
    99+
    2023-06-20
  • C#多态如何实现
    小编给大家分享一下C#多态如何实现,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C#实现多态主要有3种方法,虚方法,抽象类,接口1 虚方法在父类的方法前面加关键字...
    99+
    2023-06-14
  • C++中如何实现list
    这篇文章将为大家详细讲解有关C++中如何实现list,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。list的介绍list的优点:list头部、中间插入不再需要挪动数据,O(1)效率高list插入数据是新增...
    99+
    2023-06-20
  • C++中如何实现LeetCode
    这篇文章主要为大家展示了“C++中如何实现LeetCode”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C++中如何实现LeetCode”这篇文章吧。[LeetCode] 35. Search ...
    99+
    2023-06-20
  • C++如何实现AVL树
    本篇内容介绍了“C++如何实现AVL树”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!AVL 树的概念也许因为插入的值不够随机,也许因为经过某...
    99+
    2023-07-05
  • c++多态如何实现
    多态是面向对象编程中允许对象具有不同形式或行为的一种机制。c++ 中的多态通过虚函数、抽象类、纯虚函数和动态绑定实现。虚函数允许派生类重新定义基类方法,抽象类包含必须在派生类中重新定义的...
    99+
    2024-04-22
    c++
  • C#如何实现SQL封装
    这篇文章给大家分享的是有关C#如何实现SQL封装的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。SQLHelper.as , 代码如下:using System; usi...
    99+
    2024-04-02
  • C++如何实现堆排序
    这篇文章主要介绍“C++如何实现堆排序”,在日常操作中,相信很多人在C++如何实现堆排序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++如何实现堆排序”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!概述...
    99+
    2023-06-22
  • c++如何实现yolov5转onnx
    本篇内容介绍了“c++如何实现yolov5转onnx”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!训练模型.pt转onnx训练部分根据呼声再...
    99+
    2023-06-22
  • c++11如何实现闭包
    这篇文章主要介绍了c++11如何实现闭包,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是闭包一个函数,带上了一个状态,就变成了闭包了。那什么叫 “带上状态” 呢? 意思是...
    99+
    2023-06-15
  • C#如何实现泛型类
    这篇文章主要为大家展示了“C#如何实现泛型类”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#如何实现泛型类”这篇文章吧。使用泛型集合有些人问我"面向对象编程(OOP)的承诺在哪里?&...
    99+
    2023-06-17
  • RSA如何实现C# 加密
    RSA如何实现C# 加密,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。RSA实现C# 加密首先我们来了解下什么是RSA ,它属于不对称加密,其原理就是使用一个公...
    99+
    2023-06-17
  • C++如何实现组合项
    本篇内容主要讲解“C++如何实现组合项”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++如何实现组合项”吧!Combinations 组合项Given two integers n&...
    99+
    2023-06-20
  • C#如何实现Excel导入
    小编给大家分享一下C#如何实现Excel导入,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C# Excel导入有以下几点需要我们注意:C# Excel导入只能存储...
    99+
    2023-06-18
  • C++如何实现单链表
    小编给大家分享一下C++如何实现单链表,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!单链表的实现(从入门到熟练)概念和结构概念:链表是一种物理存储结构上非连续、非...
    99+
    2023-06-29
  • C++如何实现对象池
    这篇“C++如何实现对象池”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“C++如何实现对象池”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让我们进入主题吧。前言需求...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作