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的简单实现的更多相关文章

  1. gtest简短,简单易用

    gtest它是一种跨平台的(Liunx.Mac OS X.Windows.Cygwin.Windows CE and Symbian)的C++测试框架.有google该公司宣布. gtest台上为编写 ...

  2. 一个简单的string类,读书看报系列(一)

    对于这个类,写过程序的都知道应该含有的方法是 初始化.销毁.拼接.求长度.清除.判断是否为空等.还有一些操作符重载 一.先看初始化: 可以想到应该有默认构造的的.带有字符串的.带有默认字符的.还有一个 ...

  3. AS_简单的开始

    1.注释   单行注释  //           多行注释  /* src */ 2.变量   变量名,可以包含字母.数字.下划线.$.但不以数字开头.   变量类型,是严格数据类型.AS有静态类型 ...

  4. MyString类的实现--基础中的基础C语言

    MyString 类是学习 C++ 的过程中一个很重要的例子,涉及到面向对象的封装.堆内存申请和释放.函数的重载以及 C++ 的 “Big Three”.本例子重点在于复习和理解上述的 C++ 特性, ...

  5. 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 ...

  6. 【造轮子】打造一个简单的万能Excel读写工具

    大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...

  7. Fabio 安装和简单使用

    Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...

  8. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  9. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

随机推荐

  1. fleet - 基于Machine Metadata的任务调度

    基于Machine Metadata的任务调度 复杂和特定的要求的应用程序可以针对一个子集的集群调度通过machine metadata.强大的部署拓扑结构,可以实现的基础上的机器的地区,机架位置,磁 ...

  2. Kendo MVVM (二) ObservableObject 对象

    概述 Kendo MVVM 框架关键的一个部分为 ViewModel,它主要是通过 kendo.data.ObserableObject 来提供支持的.它可以监控改变( UI 变化或是值的变化)并通知 ...

  3. redis-----字符串操作的复杂度

    命令 含义 复杂度 set key value 设置key-value o(1) get key 获取key-value o(1) del key 删除key-value o(1) setnx set ...

  4. 查询日志logcat使用总结

    cmd命令行中使用adb logcat命令查看Android系统和应用的log,dos窗口按ctrl+c中断输出log记录.logcat日志中的优先级/tag标记: android输出的每一条日志都有 ...

  5. python基础教程总结5——函数

    1.函数创建 1).函数代码块以def关键词开头,后接函数标识符名称和圆括号()2).任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数3).函数的第一行语句可以选择性地使用文档字符串 ...

  6. Xamarin 常见问题解决方案汇总

    出现如下提示,错误: 找不到或无法加载主类 com.sun.tools.javac.MainMSB6006: 或 閿欒: 绋嬪簭鍖卆ndroid.support.v4.view.ViewPager涓嶅 ...

  7. UVA1607 Gates 与非门电路 (二分)

    题意:给你一个按发生时间的序列,表示与非门电路的输入,一开始全部输入是x,现在要改成尽量少的x,实现相同的功能. 题解:电路功能只有4中0,1,x,非x.那么如果一开始x改变了,输出结果不变,那么说明 ...

  8. ecplise——python not configured报错

    解决方法:点击window——preferences——PyDey——pythonInterprter 最后成功

  9. 2018.2.14 Java中的哈夫曼编码

    概念 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造 ...

  10. js 去除数组中的空值以及数组判断是否有重复数据

    1.判断是否有重复数据 function isRepeat(array){ var hash = {}; for(var i in array) { if(array[i]!="" ...