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托管内存)来做缓存,这样对于单个应用服务 ...
随机推荐
- 编译错误you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
解决方法: export FORCE_UNSAFE_CONFIGURE=1
- iOS 应用架构 (一)
摘要:iOS 客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来回答 iOS 应用架构中的种种问题,本文是其中的第一篇,主要讲架构设计的通识和方法论等,同时还讨论了大家关心 ...
- 在开发第一个Android应用之前需要知道的5件事:
你能否详细讲述一下,在开发Android应用过程中每一阶段要用到的技能和编程语言? 建立一个Android应用程序可以归结为两个主要技能/语言:Java和Android系统.Java是Android的 ...
- 关于纠正《Hive权威指南》中的结论~“hive在使用set自定义变量时,hivevar命名空间是可选的”~的论证
背景: 根据<Hive权威指南>上讲,在hive-0.8.0以后可以使用--define key=value命令定义用户自定义的变量以便在Hive脚本中引用.当用户使用这个功能时,Hive ...
- sizeof(int)
sizeof()操作符检测的是系统为后面()中的类型.变量等分配的内存空间的字节数,这里()中是int,就是求系统为int类型的变量分配几个字节. 在16位int平台下是2:在32位int平台下是4: ...
- 关于“为何Unicode中文字符占取2个字节,而 UTF-8却占3个字节”的网络解释修正
学到编码时,有个疑问——好好的占2字节的Unicode不用,却要用占3字节的UTF-8编码.发明 UTF-8的初衷不就是为了修正Unicode中任何字符至少占用2个字节的弊端吗? 虽然UTF-8英文字 ...
- SAP CRM Survey调查问卷的存储模型
数据库表CRM_SVY_DB_SVS,通过如下的函数CRM_SVY_DB_SVS_CREATE插入: 可以通过指定的创建者和创建时间很容易查找到特定的Survey: 调查问卷的答案明细以XML的格式存 ...
- C++11 function用法 可调用对象模板类
std::function<datatype()> ()内写参数类型 datatype 代表function的返回值 灵活的用法.. 代码如下 #include <stdio.h&g ...
- [学习笔记]Linux下mysql的基础操作
命令 #查看版本 mysql --version #进入mysql 命令 mysql -u root -p mysql -u root@localhost (没有密码的情况) #创建数据库 c ...
- 八数码问题(一) 暴力BFS + STL
八数码问题是一个经典的人工智能问题.具体问题不累述了. 思路:由于存在多组测试数据,可以考虑“打表法“.所谓打表法,即枚举所有的初始情况,记录其到达终点的路径.而在这个题目中,顺序打表会调用很多次BF ...