MyString的简单实现
MyString.h 文件
#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
using namespace std; class MyString
{
public:
/*默认的无参和cons char *参数的构造函数;
*如果不想允许MyString str="abc"类型的赋值,可将其声明为explicit
*/
MyString(const char* str=""); //复制构造函数
MyString(const MyString& other); /*重载赋值操作符,
*返回值为自身的引用是为了支持连续赋值,如str1 = str2 =str3;
*返回值为const是为了禁止(str1=str2)=str3这样的等式
*/
const MyString& operator=(const MyString& other);
const MyString& operator=(const char* str); bool operator!() const; //重载!操作符, const函数内不会改变类的数据成员 /* 重载[]操作符
*重载此操作符后可以使用下标访问对象元素,拥有和字符串数组相同的功能
*传入的值必须是无符号整数,返回一个char 引用是为了允许MyString str("abc"); str[0]='c';这样的赋值操作
*/
char& operator[](unsigned int index);
/*
*如果不想允许上面的赋值,可以返回const型,这样就只能读取了; 此外函数定义为const含有一个好处:可以被const对象访问;
*char ch =str[0];// 合法
*str[0]=ch; //非法
*/
const char& operator[](unsigned int index) const; /*重载+操作符,连接两个字符串
*为什么不把该重载函数设为类成员函数? 如果将+重载为成员函数,则左操作数必须为MyString类型
*同时,由于MyString有隐式类型转换构造函数,这里的两个参数可以使MyString类型的也可以是const char * 或者char *
*由语义可知,返回值不应为引用;
* 定义为友元是因为该函数需要访问类的私有成员,且该函数职位该类使用
*/
friend MyString operator+(const MyString& s1, const MyString& s2);
/*重载+=操作符
* 这里可以声明为类成员函数,因为左操作数肯定是MyString类型;
*/
MyString& operator+=(const MyString& other); //声明为友元函数是因为,不能再ostream内重载<< >> 操作符,返回引用是为了支持连续输出或输入
friend ostream& operator<<(ostream& os, const MyString& str);
friend istream& operator>>(istream& is, MyString& str);
~MyString(void); void Display() const;
unsigned int length(){
return strlen(str_);
}
private:
MyString& Assign(const char* str);
char* AllocAndCpy(const char* str);
char* str_;
}; #endif // _STRING_H_
MyString.cpp 文件
#pragma warning(disable:4996)
#include "MyString.h"
#include <string.h>
//#include <iostream>
//using namespace std; MyString::MyString(const char* str)
{
str_ = AllocAndCpy(str);
} MyString::MyString(const MyString& other)
{
str_ = AllocAndCpy(other.str_);
} const MyString& MyString::operator=(const MyString& other)
{
if (this == &other) // 防止自我赋值
return *this; return Assign(other.str_);
} const MyString& MyString::operator=(const char* str)
{
return Assign(str);
} MyString& MyString::Assign(const char* str)
{ char * newStr = AllocAndCpy(str);
if(newStr != NULL){
delete[] str_; // 预防在分配内存是出错,在这里分配成功后再delete
str_ = newStr;
}
return *this;
} bool MyString::operator!() const
{
return strlen(str_) != ;
} char& MyString::operator[](unsigned int index)
{
//return str_[index];
//non const 版本调用 const版本 return const_cast<char&>(static_cast<const MyString&>(*this)[index]);
} const char& MyString::operator[](unsigned int index) const
{
return str_[index];
} MyString::~MyString()
{
delete[] str_;
} char* MyString::AllocAndCpy(const char* str)
{
int len = strlen(str) + ;
char* newstr = new char[len];
memset(newstr, , len);
strcpy(newstr, str); return newstr;
} void MyString::Display() const
{
cout<<str_<<endl;
} MyString operator+(const MyString& s1, const MyString& s2)
{ MyString str = s1;
str += s2;
return str;
} MyString& MyString::operator+=(const MyString& other)
{
int len = strlen(str_) + strlen(other.str_) + ;
char* newstr = new char[len];
memset(newstr, , len);
strcpy(newstr, str_);
strcat(newstr, other.str_); delete[] str_; str_ = newstr;
return *this;
} ostream& operator<<(ostream& os, const MyString& str)
{
os<<str.str_;
return os;
} istream& operator>>(istream& is, MyString& str)
{
char tmp[];
cin>>tmp;
str = tmp;
return is;
}
main.cpp
#include "MyString.h"
#include <iostream>
using namespace std; int main(void)
{
//构造函数测试
{
MyString str;
MyString str1="nihao";
MyString str2("hello");
MyString str3=str2; cout << "str: length:"<<str.length()<<" :"<<str<<endl;
cout << "str1: length:"<<str1.length()<<" :"<<str1<<endl;
cout << "str2: length:"<<str2.length()<<" :"<<str2<<endl;
cout << "str3: length:"<<str3.length()<<" :"<<str3<<endl;
/*输出
str: length:0 :
str1: length:5 :nihao
str2: length:5 :hello
str3: length:5 :hello
*/
}
// 操作符重载测试
{
MyString str1,str2,str3;
str3 =str2 = str1 = "hello";
cout << str1 << " "<<str2<<" "<<str3<<endl; str1="";
cout << !str1 << " : "<<!str2<<endl; str2[] = 'H';
str2 += "world"; str3 = str2 + "!";
cout << "str1: length:"<<str1.length()<<" :"<<str1<<endl;
cout << "str2: length:"<<str2.length()<<" :"<<str2<<endl;
cout << "str3: length:"<<str3.length()<<" :"<<str3<<endl; /*
hello hello hello
0 : 1
str1: length:0 :
str2: length:10 :Helloworld
str3: length:11 :Helloworld!
*/
}
//内存泄露测试
{
while(true){
MyString str;
MyString str1="nihao";
MyString str2("hello");
MyString str3=str2+str1; str1="hello world";
str1.Display();
str2 += str3; }
}
return ;
}
参考文献:http://www.xuebuyuan.com/1591314.html
MyString的简单实现的更多相关文章
- gtest简短,简单易用
gtest它是一种跨平台的(Liunx.Mac OS X.Windows.Cygwin.Windows CE and Symbian)的C++测试框架.有google该公司宣布. gtest台上为编写 ...
- 一个简单的string类,读书看报系列(一)
对于这个类,写过程序的都知道应该含有的方法是 初始化.销毁.拼接.求长度.清除.判断是否为空等.还有一些操作符重载 一.先看初始化: 可以想到应该有默认构造的的.带有字符串的.带有默认字符的.还有一个 ...
- AS_简单的开始
1.注释 单行注释 // 多行注释 /* src */ 2.变量 变量名,可以包含字母.数字.下划线.$.但不以数字开头. 变量类型,是严格数据类型.AS有静态类型 ...
- MyString类的实现--基础中的基础C语言
MyString 类是学习 C++ 的过程中一个很重要的例子,涉及到面向对象的封装.堆内存申请和释放.函数的重载以及 C++ 的 “Big Three”.本例子重点在于复习和理解上述的 C++ 特性, ...
- C++之error: cannot bind non-const lvalue reference of type ‘myString&’ to an rvalue of type ‘myString’
先看代码(不想看代码可以直接看代码后的问题描述) //header.h #ifndef _HEADER_H #define _HEADER_H #define defaultSize 128 #inc ...
- 【造轮子】打造一个简单的万能Excel读写工具
大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...
- Fabio 安装和简单使用
Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
随机推荐
- MyBatis配置文件之properties属性
MyBatis提供3个方式使用properties: 1.property子元素. 2.properties文件. 3.程序代码传递. properties属性系给系统配置一些运行参数,一般放在XML ...
- AJPFX辨析GBK和UTF8的区别
GBK编码:是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符仅能存储简体中文字符. UTF-8编码:它是一种全国家通过的一种编码,如果你的网站涉及到多 ...
- ABAP事件的简单用法
1.1.事件: 用于捕获某类对象状态的改变来触发事件的方法,并进行处理 1.2.定义:可以在类或接口中进行声明 EVENTS|CLASS-EVENTS evt EXPORTING … VALUE(p ...
- 新项目升级到JFinal3.5之后的改变-着重体验自动依赖注入
最近,JFinal3.5发布,喜大普奔,我也应JBolt用户的需求,将JBolt进行了升级,实现可配置自动注入开启,支持JFinal3.5的项目生成.具体可以看:JBolt升级日志 这等工作做完后,我 ...
- SQL Server数据库log shipping 灾备(Part1 )
1.概述 Log Shipping为SQL Server提供的数据库备份过程.它可以将数据库整个复制到另一台服务器上.在这种情况下,交易日志也会定期发送到备份服务器上供恢复数据使用,这使得服务器一直处 ...
- lastlog命令
lastlog——检查某特定用户上次登录的时间 命令所在路径:/usr/bin/lastlog 示例1: # lastlog 列出所有用户,并显示用户最后一次登录的时间等信息 示例2: # lastl ...
- python_90_hashlib模块
#用于加密相关的操作,3.x里代替了2.x中的md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 import hashlib ...
- Sublime +Markdown+OmniMarkupPreviewer 搭建实时预览的markdown编辑器
浏览器实时预览 <meta http-equiv="refresh" content="0.1"> auto save 的配置 {"aut ...
- CPP-基础:新标准 C++iostream
在新的标准 C++ iostream 库中: 1. open 函数不采用第三个参数(保护参数). 2. 无法从文件句柄创建流. 3. 除了几个例外,新的标准 C++ 库中的所有名称都在 std 命名空 ...
- Python——函数入门(一)
一.理解函数 举一个例子,当我们需要重复使用一个功能的时候,不可能每次都去复制一次代码,这个时候就需要用到函数了,所谓的函数,简单来说就是给函数取一个名字,当需要用到这个功能的时候,就可以通过这个名字 ...