参考资源:
谷歌大神,《C++程序设计语言》
一,设计要求
基本要求:C++的基本数据类型中没有字符串变量。C++提高了两种字符串的表示:C风格的字符串和标准C++引入的string类。String类应由字符串数组以及其长度组成。该类至少应包含两个“私有”成员变量,
还应具有如下成员函数:
1)多种功能的构造函数;
2)析构函数;
3)重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作;
4)字符操作;
5)字符串的特性描述 ;
6)字符串赋值;
7)字符串的链接等
8)字符串的比较
9)返回指定位置的字串
10)字串交换
11)齐全的查找功能
12)替换功能
13)字串的插入
14)字串的删除
15)字串的流处理
16) 异常处理
二,代码实现(要求未完全实现)
1,"String.h"代码如下
include "iostream"
#include "windows.h"
using namespace std;
class MyString
{
public:
//默认构造函数
MyString(int size)
{
m_pChars=new char[size];
memset(m_pChars,0,size);
m_nLength=0;
maxSize=size;
}
MyString(const char *cstr)
{
int len=strlen(cstr);
m_pChars=new char[len+1];
memset(m_pChars,0,len);
strcpy_s(m_pChars,len+1,cstr);
}
MyString(int size,const char &cstr)
{
m_pChars=new char[size+1];
memset(m_pChars,'\0',size+1);
memset(m_pChars,cstr,size);
}
//析构函数
~MyString()
{
if (m_pChars!=NULL)
{
delete[] m_pChars;
m_pChars=NULL;
}
}
friend ostream& operator<< (ostream&,MyString&);//重载<<运算符
friend istream& operator>> (istream&,MyString&);//重载>>运算符
MyString& operator=(const char *cstr);//只能被重载为成员函数
char operator[](const int nPos);//只能被重载为成员函数
char at(const unsigned int nPos);
private:
int m_nLength; //获取当前 String 对象中的字符数
char* m_pChars;
int maxSize;
};
//输入运算符重载
istream& operator>>( istream &input, MyString &str )
{
input>>str.m_pChars;
int len=strlen(str.m_pChars);
str.m_nLength=len+1;
if (len > str.maxSize)
{
cerr<<"错误:输入过多的字符(输入运算符重载)。"<<endl;
cout<<"三秒后退出程序!"<<endl;
Sleep(3000);
exit(1);
}else
{
return input; //使用return可以支持连续使用>>运算符
}
}
//输出运算符重载
ostream& operator<<(ostream& os,MyString& str)
{
os << str.m_pChars << endl;
return os;
}
char MyString::operator[](const int nPos)
{
if ( nPos>strlen(m_pChars))
{
cerr<<"错误:输入过多的字符([]运算符重载)。"<<endl;
cout<<"三秒后退出程序!"<<endl;
Sleep(3000);
exit(1);
}
return m_pChars[nPos];
}
char MyString::at(const unsigned int nPos)
{
if ( nPos> strlen(m_pChars))
{
cerr<<"错误:输入过多的字符([]运算符重载)。"<<endl;
cout<<"三秒后退出程序!"<<endl;
Sleep(3000);
exit(1);
}
return m_pChars[nPos];
}
//赋值运算符重载
MyString& MyString::operator=(const char *cstr)
{
int len=strlen(cstr);
this->m_nLength=len+1;
if (len > maxSize)
{
cerr<<"错误:输入过多的字符(赋值运算符重载)。"<<endl;
cout<<"三秒后退出程序!"<<endl;
Sleep(3000);
exit(1);
}else
{
strcpy_s(m_pChars,len+1,cstr);
return *this;
}
}
(2)主测试程序
// ConsoleAppKeCheng.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include "String.h"
//#include <string>
#include <sstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
system("color 0A");
cout<<"一,MyString类的重载运算符>>以及<<"<<endl;
MyString str1(10);
cout<<"1,重载输入:请输入字符串 ";
cin>>str1;
cout<<"2,重载输出:您的字符串为 "<<str1<<endl;
cout<<"二,MyString类的构造函数 "<<endl;
MyString str2(10);
str2="Ebow";
cout<<"1,直接赋值(重载赋值运算符):"<<str2;
char *cs="Tang";
MyString str3(cs);
cout<<"2,复制构造函数:"<<str3;
char ch='E';
MyString str4(5,ch);
cout<<"3,赋值指定数目的字符:"<<str4<<endl;
cout<<"三,MyString类的字符操作"<<endl;
MyString str5 = "EbowTang";
ch = str5[1];//operator[]返回当前字符串中第n个字符的位置
cout<<"指定的字符串:"<<str5;
cout <<"用[]重载返回指定位置1的元素 "<< ch << endl;
MyString str6 = "EbowTang";
ch = str6.at(4);//at()返回当前字符串中第n个字符的位置,并且提供范围检查,当越界时会抛出异常!
cout<<"用at函数返回指定位置5的元素 " << ch << endl;
system("pause");
return 0;
}
(3)测试结果
附带一篇关于《字符串拼接效率比较文章》
最近写的程序用到大量拼接字符串,为了提高拼接效率,比较了一下+=、append、stringstream、sprintf四种拼接字符串的方法。
测试方法
比较方法是写了4个函数,分别用+=、append、stringstream、sprintf的方式来拼接字符串,拼接方法是将s1="abcedfg",s2="hijklmn",s3="opqrst"三个字符串拼接到一起,总共循环60次。然后在main函数中依次调用这4个函数,并打时间戳来计时。为了使时间差异更明显,可以取循环N(N可以为100或是1000000等)次调用的时间。代码如下:
#include <iostream>
#include <string>
#include <sys/time.h>
#include <sstream>
#include <stdio.h>
using namespace std;
#define OUT_IN_REPEATE_NUM 10000
#define IN_REPEATE_NUM 60
string s1="abcedfg";
string s2="hijklmn";
string s3="opqrst";
void plusTest(string& ret)
{
for(int i=0; i<IN_REPEATE_NUM; i++)
{
ret += s1;
ret += s2;
ret += s3;
}
}
void appendTest(string& ret)
{
for(int i=0; i<IN_REPEATE_NUM; i++)
{
ret.append(s1);
ret.append(s2);
ret.append(s3);
}
}
void sprintfTest(string& ret)
{
const size_t length=26*IN_REPEATE_NUM;
char tmp[length];
char* cp = tmp;
size_t strLength=s1.length()+s2.length()+s3.length();
for(int i=0; i<IN_REPEATE_NUM; i++)
{
sprintf(cp,"%s%s%s", s1.c_str(), s2.c_str(),s3.c_str());
cp+=strLength;
}
ret = tmp;
}
void ssTest(string& ret)
{
stringstream ss;
for(int i=0; i<IN_REPEATE_NUM; i++)
{
ss<<s1;
ss<<s2;
ss<<s3;
}
ret = ss.str();
}
int main() {
string ss, plus, append, sprintf;
struct timeval sTime, eTime;
gettimeofday(&sTime, NULL);
for(int i=0; i<OUT_IN_REPEATE_NUM; i++)
{
sprintf="";
sprintfTest(sprintf);
}
gettimeofday(&eTime, NULL);
long SprintfTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒
gettimeofday(&sTime, NULL);
for(int i=0; i<OUT_IN_REPEATE_NUM; i++)
{
append="";
appendTest(append);
}
gettimeofday(&eTime, NULL);
long AppendTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒
gettimeofday(&sTime, NULL);
for(int i=0; i<OUT_IN_REPEATE_NUM; i++)
{
ss="";
ssTest(ss);
}
gettimeofday(&eTime, NULL);
long SsTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒
gettimeofday(&sTime, NULL);
for(int i=0; i<OUT_IN_REPEATE_NUM; i++)
{
plus="";
plusTest(plus);
}
gettimeofday(&eTime, NULL);
long PlusTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒
cout<<"PlusTime is : "<<PlusTime<<endl;
cout<<"AppendTime is : "<<AppendTime<<endl;
cout<<"SsTime is : "<<SsTime<<endl;
cout<<"SprintfTime is :"<<SprintfTime<<endl;
if(ss==sprintf && append==plus && ss==plus)
{
cout<<"They are same"<<endl;
}
else
{
cout<<"Different!"<<endl;
cout<<"Sprintf: "<<sprintf<<endl;
cout<<"ss: "<<ss<<endl;
cout<<"Plus: "<<plus<<endl;
cout<<"Append:"<<append<<endl;
}
}
测试结果:
在Linux环境下用g++编译以上代码,运行结果如下(时间单位为μm):
外层循环1000000次 | 外层循环100000次 | 外层循环10000次 | 外层循环1000次 | 外层循环100次 |
PlusTime is : 3405450 AppendTime is : 4020078 SsTime is : 7835499 SprintfTime is : 14875433 They are same | PlusTime is : 337229 AppendTime is : 401719 SsTime is : 788242 SprintfTime is : 1517999 They are same | PlusTime is : 32177 AppendTime is : 40265 SsTime is : 78928 SprintfTime is : 150839 They are same | PlusTime is : 3402 AppendTime is : 4074 SsTime is : 7984 SprintfTime is : 15425 They are same | PlusTime is : 369 AppendTime is : 429 SsTime is : 921 SprintfTime is : 1591 They are same |
结论:
根据以上结果,如果是使用Linux系统并且是g++(gcc)编译器,大量拼接字符串的效率从高到低依次为:+=、append()、stringstream、sprintf()。
——菜鸟吉姆斯原创,如有错误,敬请指正!
参考资源:
【1】http://www.cnblogs.com/james6176/p/3222671.html