为了复习c++知识,简单的实现一个string类,类名为CMyString

环境说明:windows 7 64位 和 CentOS Linux release 7.6.1810 (Core)

开发工具:Visual Studio 2015 和 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)

CMyString类的头文件CMyString.h

 #include <iostream>

 #ifndef __C_MY_STRING__
#define __C_MY_STRING__ class CMyString
{
public:
//默认构造函数
CMyString();
//带参数的构造函数
CMyString(const char* str);
//拷贝构造函数
CMyString(const CMyString&);
//析构函数
~CMyString(); //重载赋值运算符
CMyString& operator=(const CMyString&);
CMyString& operator=(const char*);
//重载[]运算符(可修改)
char& operator[](const int);
//重载[]运算符(不可修改)
const char& operator[](const int) const;
//重载==运算符
bool operator==(const CMyString&) const;
//重载!=运算符
bool operator!=(const CMyString&) const;
//重载>运算符
bool operator>(const CMyString&) const;
//重载<运算符
bool operator<(const CMyString&) const;
//重载>=运算符
bool operator>=(const CMyString&) const;
//重载>=运算符
bool operator<=(const CMyString&) const;
//重载<<运算符
friend std::ostream& operator<<(std::ostream&, const CMyString &);
private:
char* m_pdata;
}; #endif // !__C_MY_STRING__

CMyString类的实现文件CMyString.cpp

 #include "CMyString.h"
#include <cstring>
using namespace std; CMyString::CMyString()
{
//创建一个空的data,占一个字节空间
m_pdata = new char[];
m_pdata[] = '\0';
cout << "默认构造函数" << endl;
} CMyString::CMyString(const char * str)
{
if (str)
{
int len = strlen(str);
m_pdata = new char[len+];
strncpy(m_pdata, str, len);
m_pdata[len] = '\0';
}
else
{
//创建一个空的data,占一个字节空间
m_pdata = new char[];
m_pdata[] = '\0';
}
cout << "带参数的构造函数" << endl;
} CMyString::CMyString(const CMyString & inString)
{
int len = strlen(inString.m_pdata);
m_pdata = new char[len +];
strncpy(m_pdata, inString.m_pdata, len);
m_pdata[len] = '\0';
cout << "拷贝构造函数" << endl;
} CMyString::~CMyString()
{
delete[] m_pdata;
m_pdata = nullptr;
cout << "析构函数" << endl;
} CMyString & CMyString::operator=(const CMyString & instring)
{
cout << "重载赋值运算符1" << endl;
//如果是同一个对象,不做处理直接返回
if (this == &instring)
{
return *this;
} //使用入参通过拷贝构造函数创建一个临时对象
CMyString tmpString(instring);
//修改data指针,当函数结束时,tmpString对象过期,将自动调用析构函数,把原来当前对象的data地址释放掉
char* tmpData = tmpString.m_pdata;
tmpString.m_pdata = m_pdata;
m_pdata = tmpData;
return *this;
} CMyString & CMyString::operator=(const char * str)
{
cout << "重载赋值运算符2" << endl;
delete m_pdata;
if (str)
{
int len = strlen(str);
m_pdata = new char[len + ];
strncpy(m_pdata, str, len);
m_pdata[len] = '\0';
}
else
{
//创建一个空的data,占一个字节空间
m_pdata = new char[];
m_pdata[] = '\0';
}
return *this;
} char & CMyString::operator[](const int index)
{
cout << "重载[]运算符(可修改)" << endl;
return m_pdata[index];
} const char& CMyString::operator[](const int index) const
{
cout << "重载[]运算符(不可修改)" << endl;
return m_pdata[index];
} bool CMyString::operator==(const CMyString & inString) const
{
cout << "重载==运算符" << endl;
return !strcmp(m_pdata, inString.m_pdata);
} bool CMyString::operator!=(const CMyString & inString) const
{
cout << "重载!=运算符" << endl;
return strcmp(m_pdata, inString.m_pdata);
} bool CMyString::operator>(const CMyString & inString) const
{
cout << "重载>运算符" << endl;
return (strcmp(m_pdata, inString.m_pdata) > );
} bool CMyString::operator<(const CMyString & inString) const
{
cout << "重载<运算符" << endl;
return (strcmp(m_pdata, inString.m_pdata) < );
} bool CMyString::operator>=(const CMyString & inString) const
{
cout << "重载>=运算符" << endl;
return (strcmp(m_pdata, inString.m_pdata) >= );
} bool CMyString::operator<=(const CMyString & inString) const
{
cout << "重载<=运算符" << endl;
return (strcmp(m_pdata, inString.m_pdata) <= );
} ostream & operator<<(ostream & os, const CMyString & instring)
{
os << instring.m_pdata;
return os;
}

CMystring类的测试文件testCMyString.cpp

 #include <iostream>
#include "CMyString.h" using namespace std;
int main()
{
//带参数的构造函数
const CMyString myString1("abc");
//默认构造函数
CMyString myString2;
//重载赋值运算符2
myString2 = "def";
//默认构造函数
CMyString myString3;
//重载赋值运算符1,(这个类的内部实现是先调用拷贝构造函数生成一个临时变量,再使用临时变量通过把内容给到myString3,再把临时变量析构)
myString3 = myString2;
//拷贝构造函数
CMyString myString4(myString2);
myString3[] = 'e'; cout << myString1 << "\t" << myString2 << "\t" << myString3 << endl;
//由于myString1带了const修饰,因此是不可修改的,调用不可修改的重载[]运算符
cout << myString1[] << endl;
cout << (myString1 != myString2) << endl;
cout << (myString1 == myString2) << endl;
cout << (myString1 < myString2) << endl;
cout << (myString1 <= myString2) << endl;
cout << (myString1 > myString2) << endl;
cout << (myString1 >= myString2) << endl;
return ;
}

VS2015测试结果:

CentOS

编译

g++ -o testCMyString -std=c++0x ./*.cpp

测试结果

一个简单实现的string类的更多相关文章

  1. 如何用C++封装一个简单的数据流操作类(附源码),从而用于网络上的数据传输和解析?

    历史溯源 由于历史原因,我们目前看到的大部分的网络协议都是基于ASCII码这种纯文本方式,也就是基于字符串的命令行方式,比如HTTP.FTP.POP3.SMTP.Telnet等.早期操作系统UNIX( ...

  2. java使用注解和反射打造一个简单的jdbc工具类

    a simple jdbc tools 如有转载和引用,请注明出处,谢谢 1. 定义我们需要的注解 要想实现对数据库的操作,我们必须知道数据表名以及表中的字段名称以及类型,正如hibernate 使用 ...

  3. 通过一个简单的数据库操作类了解PHP链式操作的实现

    class Model{ public $table; //操作的表; private $opt; //查询的参数; private $pri; //表的主键; private $lastSql; / ...

  4. 一个简单的redis调用类

    能只能判断函数的调用规则,容错规则, 例如set函数 set($key, $value, $time = false) 根据time的真假来判断是否使用set,或者是setex函数 get函数 get ...

  5. 20181015记录一个简单的TXT日志类

    20190422添加换行以及时间记录 using System; using System.Collections.Generic; using System.IO; using System.Lin ...

  6. 一个简单的php分页类代码(转载)

    入门级php分页类 原文地址:http://www.xfcodes.com/php/fenye/3608.htm 时间:2015-12-16 20:52:00来源:网络 php分页类. 复制代码代码如 ...

  7. 一个简单的Hibernate工具类HibernateUtil

    HibernateUtil package com.wj.app.util; import org.hibernate.Session; import org.hibernate.SessionFac ...

  8. 一个简单的CI分页类

    [php] view plaincopy <span style="font-size:16px;">/** * * 关于 页码有效性的判断需要加在 控制器中判断,即当 ...

  9. 自己实现简单的string类

    1.前言 最近看了下<C++Primer>,觉得受益匪浅.不过纸上得来终觉浅,觉知此事须躬行.今天看了类类型,书中简单实现了String类,自己以前也学过C++,不过说来惭愧,以前都是用C ...

随机推荐

  1. ROLLUP、CUBE、GROUP BY的使用区别

    1.ROLLUP:根据维度在数据结果集中进行的聚合操作,可多维度SELECT count(*) num,MONTH(register_time) times,`status` FROM `user` ...

  2. [linux]查看进程占用内存

    1.top -p 进程ID PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 NInice:值 VIRT:进程占用的虚拟内存 RES:进程占用的物理内存 SHR:进程使 ...

  3. etcd启动报错:couldn't find local name "default" in the initial cluster configuration

    启动etcd的时候报错: # systemctl restart etcd Job for etcd.service failed because the control process exited ...

  4. Spark连续特征转化成离散特征

    当数据量很大的时候,分类任务通常使用[离散特征+LR]集成[连续特征+xgboost],如果把连续特征加入到LR.决策树中,容易造成overfit. 如果想用上连续型特征,使用集成学习集成多种算法是一 ...

  5. Android设置顶部banner背景透明度时影响全局背景问题

    项目中用到滑动界面使顶部title栏背景渐隐渐现的效果,即初始不滑动时的透明度为0,用了bannerle.getBackground().setAlpha(0); 但使用这个方法设置透明度是管用,返回 ...

  6. SDN实验---Ryu的应用开发(四)北向接口RESTAPI

    一:推文 软件定义网络基础---REST API概述 软件定义网络基础---REST API的设计规范 二:掌握Ryu基本RESTAPI使用方法 (一)Ryu的RESTAPI (二) REST应用样例 ...

  7. Egret《决战沙城》框架学习

    源码地址:https://github.com/yicaoyimuys/EgretGameEngine 虽然走花观马看了看,但是收获还是蛮多. mvc: BaseController          ...

  8. laydate.render报错:日期格式不合法

    在使用laydate渲染日期时: laydate.render({ elem: '#day' }); 提示日期格式不合法 需要使用 too.dateType()来包装 <input type=& ...

  9. 历时一年《Python自动化测试实战》终于出版!!!

    一.为什么会写这本书 1.系统梳理.可以加深自己对测试知识体系的系统梳理 2.名气.增加个人的名气,比如:面试时,可以很自豪的说,我是xxxx书的作者 3.利他.帮助有需要的学习者更系统.完备的学习和 ...

  10. Linux下tar的安装方式

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...