C++string类的实现

当类的成员对象包含指针类型时,拷贝构造赋值运算符重载采用浅拷贝不写即默认采取值拷贝的形式。

若类的成员对象为指针类型时,若不自定义**“拷贝构造”“赋值运算符重载”**会出现一种情况即指针悬挂,如下情况:
浅拷贝:
简单的赋值浅拷贝

     String s1("himark");
     Stirng s2=s1;

S1和S2包含的指针对象同时指向一块内存
析构时delete会析构两次这个内存块,导致程序崩溃

深拷贝:

     String s1("himark");
     Stirng s2=s1;

构造S2时拷贝一块与S1数据块一样大的内存,并将值拷贝下来
使得S1,S2指向自己的数据块,析构时各自释放自己的数据块

自主实现String类

#pragma once
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

class String
{
    //输出运算符重载的友元函数
    friend ostream& operator<<(ostream& _cout, const String& s);
    //输入运算符重载的友元函数
    friend istream& operator>>(istream& _cin , String& s);
    
public:
    //构造函数
    String(const char* str)    
        :_str(new char[strlen(str)+1])
        , _size(strlen(str))
        , _capacity(strlen(str)+1)
    {
        strcpy(_str, str); // '\0‘也拷贝了
    }
    
    //拷贝构造函数  String s2(s1)
    String(const String& s)
        //深拷贝
         :_str(new char[strlen(s._str)+1])
         , _size(strlen(s._str))
         , _capacity(strlen(s._str)+1)
    {
        _str=s._str;
        _size=s._size;
        _capacity=s._capacity;
    }

    //析构函数
    ~String()
    {
        if(_str)
        {
            delete[] _str;  //动态释放空间
            _str = NULL;
        }
    }

    const char* c_str()
    {
        return _str;
    }
    //增删改查
    void Expand(size_t n);
    void PushBack(char ch);
    void PushBack(const char* str);
    void PopBack();
    void Insert(size_t pos, char ch);
    void Insert(size_t pos, const char* str);
    void Erase(size_t pos, size_t n);

    size_t Find(char ch) const ;
    size_t Find(const char* str)const;

    void Swap(String& s);
    
    //操作符重载
    
    //s1=s2
    String& operator=(String s);
    //s1 + 'a'   传值返回
    String operator+(char ch);
    //s1 += 'a'   传引用返回
    String& operator+=(char ch);
    //s1 +  "str"  传值返回
    String operator+(const char* str)
    //s1 += "str"  传引用返回
    String& operator+=(const char* str);

    bool operator<(const String& s) const ;
    bool operator<=(const String& s) const ;
    bool operator>(const String& s) const ;
    bool operator>=(const String& s) const ;
    bool operator==(const String& s) const ;
    bool operator!=(const String& s) const ;

private:
    char* _str;                   //保存字符串 
    size_t size;                 //大小
    size_t _capacity;            //有效长度

};

//输出运算符的重载
ostream& operator<<(ostream& _cout, const String& s)
{
    _cout<<"str: "<<s._str<<" size:"<<s._size<<" capacity:"<<s._capacity<<endl;
    return _cout;
}
//输入运算符的重载
istream& operator>>(istream& _cin, String& s)
{
    _cin>>s._str;
    return _cin;
}

//函数实现

#include"string.h"
#include<assert.h>


//扩容
void String::Expand(size_t n) 
{
    if(n>_capacity)
    {
        _str=(char*)realloc(_str, n+1);
        _capacity=n+1;
    }

}
//=========================================
//增删改查


void String::PushBack(char ch)
{
    if(_size>=_capacity-1)
    {
        Expand(_capacity*2);
    }
    _str[_size]=ch;
    _size++;
    _str[_size]='\0';    
}

void String::PushBack(const char* str)
{
    sizez_t len=strlen(str);
    if(len+_size>=_capacity-1)
    {
        Expand(len+size);
    }
    strcpy(_str+_size,str);
    _size=strlen(_str);
}

void String::PopBack()
{
    if(_size>0)
    {
        //将'\0'前移
        _str[_size-1]=_str[_size];
        --_size;
    }
}
    
void String::Insert(size_t pos, char ch)
{
    if(_size>=_capacity)
    {
        Expand(_capacity*2);
    }
    size_t end=_size;
    while(end>=pos)
    {
        _str[end+1]=_str[end];
        --end;
    }
    _str[pos]=ch;
    ++_size;
}
void String::Insert(size_t pos, const char* str)
{
    size_t len=strlen(str);
    size_t tmp=len;
    if(_size+len>_capacity)
    {
        Expand(_size+len);
    }
    size_t end=_size;
    while(end>=pos)
    {
        _str[end+len]=_str[end];
        --end;
    }
    while(len-- >0)
    {
        _str[pos++]= *str++;
    }
    _size+=tmp;
}

void String::Erase(size_t pos, size_t n)
{
    if(pos+n>=_size-1)
    {
        _str[pos]='\0';
        _size=pos;
    }
    else
    {
        strcpy(_str+pos, _str+pos+n);  //直接将'\0'拷贝到pos处
        _size-=n;
    }
}

size_t String::Find(char ch) const
{
    for(size_t i=0;i<_size;++i)
    {
        if(_str[i]==ch)
        {
            return i;
        }
    }
    return -1;
}

size_t String::Find(const char* str) const
{
    assert(str);
    char* start=(char*)_str;
    char* substart=(char*)str;
    char*ret=(char*)_str;
    while(*ret)
    {
        start=ret;
        if(*start&&*substart&&(*start==*substart))
        {
            ++start;
            ++substrat;
        }
        if(*substart=='\0')
        {
            return 1;
        }
        substart=(char*)str;
        ret++;
    }
    return -1;
}

//s1.Swap(s2)
void String::Swap(String&s)
{
    if(*this!=s)
    {
        swap(_str, s._str);
        swap(_size,s._size);
        swap(_capacity,s._capacity);
    }
}

//s1=s2  现代写法
String& String::operator=(String s)
{
    if(tihs!=&s)
    {
        _size=s._size;
        _capacity=s._capacity;
        swap(_str,s._str);
    }
    return *this;
}

String String::opreator+(const char* str)
{
    string *s=new String;
    s->_size=_size+strlen(str);
    s->_capacity=_capacity+strlen(str);
    s->_str=new char[s->_size+1];
    strcpy(s->_str,_str);
    strcat(s->_str,str);
    return *s;
}

String& String::operator+=(const char* str)
{
    _size+=strlen(str);
    _capacity+=strlen(str);
    char *s=new char[_size+1];
    strcpy(s,_str);
    strcat(s,str);
    delete[]_str;
    _str=s;
    return *this;
}


bool String::operator<(const String& s) const 
{
    size_t i=0;
    for(;i<_size&&i<s._size;++i)
    {
        if(_str[i]<s._str[i])
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    if(i==_size)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool String::operator<=(const String& s) const
{
    return *this<s||*this==s;
}

bool String::operator>(const String& s) const
{
    return !(*this<=s);
}

bool String::operator>=(const String& s) const
{
    return !(*this<s);
}

bool String::operator==(const String& s) const
{
    size_t i=0;
    for(;i<_size&&i<s._size;++i)
    {
        if(_str[i]!=s.str[i])
        {
            return false;
        }
    }
    if(i==_size&&i==s._size)
    {
        return true;
    }
    return false;
}

bool String::operator!=(const String& s) const
{
    return !(*this==s);
}

int main()
{
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值