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托管内存)来做缓存,这样对于单个应用服务 ...
随机推荐
- [转]Todd.log - a place to keep my thoughts on programming 分布式架构中的幂等性
Todd.log - a place to keep my thoughts on programming 理解HTTP幂等性 基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式. ...
- 5.类型、值和变量-JavaScript权威指南笔记
开始变得有意思起来了,然而第三章还是以基础知识了解的角度阐释相关的概念,并没有深入到结合代码以及要实现的功能讲用法和原理的程度. 1.概论. value:程序的运行是对值的操作. type:能够表示并 ...
- Java基础语法(数组)
第4天 Java基础语法 今日内容介绍 u 流程控制语句(switch) u 数组 第1章 流程控制语句 1.1 选择结构switch switch 条件语句也是一种很常用的选择语句,它和if条件语句 ...
- c++中三种继承方式的区别
public公有继承 protected保护继承 private私有继承 我们知道类的private和protected成员,在类外是不可以使用的.只有public成员可以在类外直接使用. 公有继承时 ...
- To run dex in process, the Gradle daemon needs a larger heap
http://blog.csdn.net/u012995856/article/details/52595653
- Android笔记--View绘制流程源码分析(二)
Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...
- git如何强制用远程分支更新本地
git本地即使有修改如何强制更新: 本地有修改和提交,如何强制用远程的库更新本地.我尝试过用git pull -f,总是提示 You have not concluded your merge. (M ...
- python3操作mysql数据库表01(基本操作)
#!/usr/bin/env python# -*- coding:UTF-8 -*- import requestsfrom bs4 import BeautifulSoupfrom bs4 imp ...
- Python3+Selenium3+webdriver学习笔记7(选择多链接的结果、iframe、下拉框)
#!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriverfrom selenium.webdriver.co ...
- Android中一个关于ListView的奇怪问题
今天在做项目的时候发现了一个比较奇怪的问题,是关于ListView的,即ListView的android:height属性会影响程序中ListView的getView()方法的调用次数,如果设置Lis ...