以下是在学习过程中,对标准模板库中的string类的模拟实现
#include <cstdlib>
#include <iostream>
using namespace std;
int strlen(const char * s)
{ int i = 0;
for(; s[i]; ++i);
return i;
}
void strcpy(char * d,const char * s)
{
int i = 0;
for( i = 0; s[i]; ++i)
d[i] = s[i];
d[i] = 0;
}
int strcmp(const char * s1,const char * s2)
{
for(int i = 0; s1[i] && s2[i] ; ++i) {
if( s1[i] < s2[i] )
return -1;
else if( s1[i] > s2[i])
return 1;
}
return 0;
}
void strcat(char * d,const char * s)
{
int len = strlen(d);
strcpy(d+len,s);
}
class MyString
{
char *s;
public:
MyString(const char *c){
s=new char[strlen(c)+1];
strcpy(s,c);
}
MyString(const MyString &p){
s= new char[strlen(p.s)+1];
strcpy(s,p.s);
}
MyString(){
s=new char[1];
s[0]='\0';
}
~MyString() {
if (s) delete[] s;
}
MyString& operator =(const MyString &p){
delete s;
s= new char[strlen(p.s)+1];
strcpy(s,p.s);
return *this;
}
MyString& operator =(const char *p){
delete s;
s= new char[strlen(p)+1];
strcpy(s,p);
return *this;
}
friend ostream& operator <<(ostream &o,const MyString &s){
o<<s.s;
return o;
}
friend MyString operator+(const MyString &s1,const MyString &s2){
char * temp=new char[strlen(s1.s)+strlen(s2.s)+1];
strcpy(temp,s1.s);
strcat(temp,s2.s);
MyString s(temp);
return s;
}
friend MyString operator+(const MyString &s1,const char *s2){
char * temp=new char[strlen(s1.s)+strlen(s2)+1];
strcpy(temp,s1.s);
strcat(temp,s2);
MyString s(temp);
return s;
}
char& operator [](int i){
return s[i];
}
MyString operator ()(const int star,const int len){
char *temp=new char[len+1];
strcpy(temp,this->s+star);
temp[len]='\0';
MyString ss(temp);
return ss;
}
MyString& operator +=(const char * p){
char *temp=new char[strlen(this->s)+strlen(p)+1];
strcpy(temp,this->s);
strcat(temp,p);
delete s;
s=temp;
return *this;
}
friend int operator <(MyString &s1,MyString& s2){
for(int i = 0; s1[i] && s2[i] ; ++i) {
if( s1[i] < s2[i] )
return 1;
else return 0;
}
return 0;
}
friend int operator >(MyString &s1,MyString &s2){
for(int i = 0; s1[i] && s2[i] ; ++i) {
if( s1[i] > s2[i] )
return 1;
else return 0;
}
return 0;
}
friend int operator ==(MyString &s1,MyString &s2){
if(strlen(s1.s)==strlen(s2.s)){
int i=0;
for(i = 0; s1[i] && s2[i] ; ++i) {
}
if(i<strlen(s1.s))return 0;
else return 1;
}
else
return 0;
}
};
int CompareString( const void * e1, const void * e2)
{
MyString * s1 = (MyString * ) e1;
MyString * s2 = (MyString * ) e2;
if( * s1 < *s2 )
return -1;
else if( *s1 == *s2)
return 0;
else if( *s1 > *s2 )
return 1;
}
闭坑点
1.对运算符 () [] ->的重载时,重载函数必须声明为类的成员函数
2.关于深拷贝和浅拷贝的问题
如果使用默认的赋值函数,只会对对象里面的成员变量进行字节复制,既cope每个字节的内容,会导致两个不同的对象里面的指针指向了同一块内存,容易导致两个问题:1.某个对象消亡对他的内存delete之后,另一个对象找不到这块内存的东西 2.第二个对象消亡对同一块内存会delete两次
3.引用作为函数的返回值
作用:可以减少对象的构造
在c++中函数调用,函数返回对象都会调用一次复制构造函数,生成一个临时的变量。
使用场景:1.函数返回值是this指针,使用引用返回减少复制构造函数调用
2.返回值是函数的参数对象
3.不能用:
对于函数中创建在栈区的临时变量,不能对其返回引用,因为对象在函数结束后会进行析构消亡
那如果在函数中使用new在堆区创建对象,返回其引用可以吗?
答案是不建议
因为在函数里面调用了new,虽然内存不会在函数结束后被释放消亡,但是在函数外面我们以为创建的是一个普通的局部变量,所以极大可能会忘记对其内存是delete释放,容易造成内存泄露