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. JS的使用

    Javascript代码在浏览器中运行,做出更流畅.优美的页面效果,增强用户体验与java是完全不同的东西,只是名称类似而已写在<script></script>标签中 大小写 ...

  2. MariaDB 实现主从复制

    實驗目的: MariaDB為MySQL的一個分支,其完全開源.無版權之虞且操作上與 MySQL 一脈相承,實際應用中非常廣泛,軟件本身很小,安裝容易,使用簡單. 但其也有缺點,指令行方式操作,無原生G ...

  3. 超文本传输协议(HTTP)

    超文本传输协议(HyperText Transfer Protocol,Http)是从服务器传输数据到客户端的传输协议. HTTP协议的主要特点可概括如下: 1.支持客户/服务器模式. 2.简单快速: ...

  4. 在CentOS7上源码安装php7--Install php7 from source on CentOS7

    首先下载php源码包并解压: # wget http://cn2.php.net/get/php-7.0.9.tar.gz/from/this/mirror # .tar.gz # cd php- 然 ...

  5. js黑科技,使用offsetParent检测元素是否隐藏

    var isHidden = function (element) { return (element.offsetParent === null);}; eg:

  6. 织梦channel标签中currentstyle不生效

    文件:/include/taglib/channel.lib.php line约133行:if( ($row['id']==$typeid || ($topid==$row['id'] &&a ...

  7. Unity四元素运用之风向标跟随箭头

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class WindVane ...

  8. [视觉识别]OpenCV + CNN 大神符识别

    数据集 Mnist数据集:http://yann.lecun.com/exdb/mnist/ 训练 import numpy as np from keras.datasets import mnis ...

  9. DaemonSet 典型应用场景【转】

    Deployment 部署的副本 Pod 会分布在各个 Node 上,每个 Node 都可能运行好几个副本.DaemonSet 的不同之处在于:每个 Node 上最多只能运行一个副本. DaemonS ...

  10. graphviz 绘制架构图

    架构图: 1.依赖调用关系.(类似文献引用关系, graphviz 自动将每一次调用升一次层级) 2.依赖调用可能是上下层级调用,也可能是同层级引用. 需人工去梳理出这些关系 3. 引用多的用颜色标识 ...