当前位置: 首页 > news >正文

门户网站开发报价单郑州优化网站公司

门户网站开发报价单,郑州优化网站公司,电子商务营销优势,建设工程招标专业网站⭐本篇重点:string类的模拟,自己实现一个简单的string类 ⭐本篇代码:c学习/05.string类的学习 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. 经典string类的模拟 1.1 深浅拷贝问题 1.2 使用深拷贝完成经典string类的…

⭐本篇重点:string类的模拟,自己实现一个简单的string类

⭐本篇代码:c++学习/05.string类的学习 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. 经典string类的模拟

1.1 深浅拷贝问题

 1.2 使用深拷贝完成经典string类的模拟

a size函数

b 拷贝构造函数

 c 赋值运算符重载

d operator[]重载

二. 现代写法的string类模拟

2.1 拷贝构造函数

 2.2 赋值运算符重载

三. 下篇文章:STL中vector的使用 


一. 经典string类的模拟

        实现一个简单的string类,主要是实现string类的构造函数,析构函数,拷贝构造函数,赋值运算符重载。这个过程需要我们首先理解深浅拷贝的问题。

1.1 深浅拷贝问题

        浅拷贝问题:如果我们初始化一个对象的时候,只是简单的将另一个对象的值赋值给这个对象。比如我们在堆上申请的空间。当我们销毁这两个对象的时候,由于它们指向同一个空间,这个空间就会被销毁两次。程序就会崩溃

测试代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1]){cout << "调用构造函数" << endl;strcpy(_str, str);}//拷贝构造string(const string& str){*this = str;}~string(){cout << "调用析构函数" << endl;delete[] _str;}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2 = "abcdef";s1.print();s2.print();return 0;
}

没有调用拷贝构造函数,可以正常输出。

运行结果如下:

如果我们使用拷贝构造函数

int main()
{yzc::string s1 = "123456";yzc::string s2(s1);return 0;
}

分析代码可知,由于浅拷贝问题。输出一次调用构造函数和两次析构函数后程序崩溃

只有使用深拷贝,我们在拷贝构造函数里面重新申请一份空间,然后重新全部复制才行。 

 1.2 使用深拷贝完成经典string类的模拟

a size函数

        为了完成深拷贝,我们需要定义一个size函数用于求_str的长度。加上const,因为函数内部并不会更改任何值

		int size()const{return strlen(_str);}

b 拷贝构造函数

与构造函数类似,我们重新开辟一份空间,然后使用strcpy进行拷贝

​//拷贝构造,使用深拷贝完成拷贝string(const string& s):_str(new char[s.size()]){strcpy(_str, s._str);}

测试代码: 

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1])	//由于C语言字符串后面都带'\0',需要加上1{strcpy(_str, str);}拷贝构造//string(const string& str)//{//	*this = str;//}//拷贝构造,使用深拷贝完成拷贝string(const string& s):_str(new char[s.size() + 1])    //一定要注意要加1,否则会越界访问{strcpy(_str, s._str);}~string(){delete[] _str;_str = nullptr;}int size()const{return strlen(_str);}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2(s1);s1.print();s2.print();return 0;
}

测试结果 

 c 赋值运算符重载

与拷贝构造函数一样,要注意深浅拷贝的问题

		//赋值运算符重载string& operator=(const string& s){if (this != &s)//地址不同才进行赋值{delete[] _str; //释放原地址空间,防止内存泄漏//定义中间变量tmp用于拷贝char* tmp = new char[s.size() + 1]; //注意要 + 1strcpy(tmp, s._str);_str = tmp;}return *this; //返回当前对象,为了支持 a = b = c}

 测试:主函数代码如下

int main()
{yzc::string s1 = "123456";yzc::string s2 = "abcdef";yzc::string s3 = s1;yzc::string s4;s4 = s2;s3.print();s4.print();return 0;
}

测试结果:

d operator[]重载

我们还能重载[]这个操作符,方便我们遍历整个字符串

直接输入i,返回_str[i]即可(注意const) 

		char& operator[](size_t i){assert(i < size());return _str[i];}const char& operator[](size_t i)const{assert(i < size());return _str[i];}

测试代码:

int main()
{yzc::string s1 = "159753468244";for (int i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;return 0;
}

运行结果:

二. 现代写法的string类模拟

2.1 拷贝构造函数

         为了提高代码的复用,我们在拷贝构造函数中使用构造函数去构造一个对象,然后交换当前对象和这个对象。

代码如下:

		//现代版写法string(const string& s):_str(nullptr){string strTmp(s._str); //使用构造函数将s._str构造一个tmpswap(_str, strTmp._str);//交换_str和tmp}

交换后,strTmp由于是局部变量就直接被销毁了! 而我们创建的对象被保留

 2.2 赋值运算符重载

我们使用传值方法传参,交换_str后我们成功创建的对象。且不会影响传入的对象

//现代版写法string& operator=(string s) //不使用引用传参,而是传值{swap(_str, s._str);return *this;}

测试代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1])	//由于C语言字符串后面都带'\0',需要加上1{strcpy(_str, str);}拷贝构造,使用深拷贝完成拷贝//string(const string& s)//	:_str(new char[s.size() + 1]) //注意要加1//{//	strcpy(_str, s._str);//}//现代版写法string(const string& s):_str(nullptr){string strTmp(s._str); //使用构造函数将s._str构造一个tmpswap(_str, strTmp._str);//交换_str和tmp}赋值运算符重载//string& operator=(const string& s)//{//	if (this != &s)//地址不同才进行赋值//	{//		delete[] _str; //释放原地址空间,防止内存泄漏//		//定义中间变量tmp用于拷贝//		char* tmp = new char[s.size() + 1];//		strcpy(tmp, s._str);//		_str = tmp;//		//	}//	return *this; //返回当前对象,为了支持 a = b = c//}//现代版写法string& operator=(string s) //不使用引用传参,而是传值{swap(_str, s._str);return *this;}~string(){delete[] _str;_str = nullptr;}size_t size()const{return strlen(_str);}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2(s1);yzc::string s3 = s1;s1.print();s2.print();s3.print();return 0;
}

运行结果:

三. 下篇文章:STL中vector的使用 

http://www.hkea.cn/news/869098/

相关文章:

  • 重庆网站建设设计公司信息ip网站查询服务器
  • 网站积分的作用seo搜索引擎优化就业前景
  • 珠海网站品牌设计公司简介最新国内新闻重大事件
  • 广东专业网站客服软件定制站长统计app下载大全
  • 广东网站建设公司排名磁力帝
  • 胶南网站建设哪家好成都电脑培训班零基础
  • 集团网站建设哪家好网上推广怎么弄?
  • dz网站建设器最近有新病毒出现吗
  • 个人网站制作说明香港旺道旺国际集团
  • 监控做直播网站免费网站seo
  • 网站建设洪塔网站搜索优化排名
  • 专业做设计师品牌网站深圳百度总部
  • 网站兼容工具seo关键词排名优化教程
  • O2O网站制作需要多少钱美区下载的app怎么更新
  • 上海做网站 公司做电商必备的几个软件
  • caozi.com网站建设中百度指数如何分析数据
  • 互联网舆情处置公司武汉seo外包平台
  • 消防器材网站建设背景seo工作职位
  • 专业网站制作公司名称seo咨询茂名
  • 做b2c网站建网站seo
  • 代理注册香港公司seo技术交流论坛
  • 想要提高网站排名应该怎么做seo网站推广费用
  • 专业做食材网站seo链接优化建议
  • 做画册的网站附近哪里有计算机培训班
  • 大兴建站推广google登录
  • 长春个人做网站哪家好百度指数热度榜
  • 嘉兴手机网站开发费用百度学术论文官网入口
  • 刷业务网站怎么做seo关键词挖掘
  • 企业移动网站品牌苏州网站外包
  • 网站建设流程 文档东莞seo技术