String class by C++

I spend three hours for this class today. It is a very interesting to consider the detail  about how to make it more elegant. Now I will share with you guys, and expect for your comments.

SelfString.h
#ifndef SELF_STRING_H
#define SELF_STRING_H

#include <iostream>
using std::ostream;
using std::istream;

class String
{
public:
    String(const char* str=NULL);
    String(const String& other);
    String& operator=(const String& other);
    ~String();

    char& operator[](unsigned int index);
    
    String& operator+=(const String& other);
    String& operator+=(const char* str);
    //bool operator==(const String& right) const;
    //bool operator!=(const String& right) const;
    
    int length() const;
    const char* c_str() const;
    bool empty() const;
    void swap(String& other);
    void append(const char* str);
    void append(const String& other);
    
    operator const char*() const;
    
    /*
    //Supply the friend method is not a good idea, it will break the encapsulation.
    friend ostream& operator<<(ostream& ostr, const String& str);
    friend istream& operator>>(istream& istr, String& str);
    */

private:
    unsigned int _length;
    char* _Data;
};

String operator+(const String& left, const String& right);
String operator+(const char* left, const String& right);
String operator+(const String& left, const char* right);

bool operator==(const String& left, const String& right);
bool operator!=(const String& left, const String& right);

ostream& operator<<(ostream& ostr, String& str);
istream& operator>>(istream& istr, String& str);

#endif



SelfString.cpp
#include "SelfString.h"
#include <string>

String::String(const char *str)
{
    if(!str || (str[0] =='\0'))
    {
        //must use new[1], not new. 
        //Or else you need to do lot of useless works to identify the delete and delete[].
        this->_Data = new char[1];
        _Data[0]='\0';
        _length = 0;
    }
    else
    {
        _length = strlen(str);
        this->_Data = new char[_length + 1];
        strcpy(_Data, str);
    }
}

String::String(const String &other)
{
    if(other._Data [0] == '\0')
    {
        _Data = NULL;
        _length = 0;
    }
    else
    {
        _Data = new char[other._length+1];
        _length = other._length;
        strcpy(_Data, other._Data);
    }
}

String::~String()
{
    //Because of _Data are all applied by new[]
     delete[] _Data;
    _Data = NULL;
}

int String::length() const
{
    return _length;
}

bool String::empty() const
{
    if(_length == 0)
    {
        return true;
    }
    return false;
}

void String::swap(String& other)
{
    if(other._Data[0] != '\0')
    {
        char* temp = new char[other._length + 1];
        strcpy(temp, other._Data);
        int len = other._length;
        
        delete[] other._Data;
        other._Data = new char[_length+1];
        strcpy(other._Data, _Data);
        
        delete[] _Data;
        _Data = new char[other._length + 1];
        _length = len;
        strcpy(_Data, temp); 
    }
    else
    {
        delete[] other._Data;
        other._Data = new char[_length+1];
        strcpy(other._Data, _Data);
        
        delete[] _Data;
        _Data = new char;
        _length = 0;
        _Data[0] = '\0';
    }
}

void String::append(const char* str)
{
    if(str && (str[0]!='\0'))
    {
        int len = strlen(str);
        char* temp = new char[_length+1];
        strcpy(temp, _Data);
        
        delete[] _Data;
        _Data = new char[_length + len + 1];

        strcpy(_Data, temp);
        strcpy(_Data+_length, str);
        _length += len;
        *(_Data + _length)='\0';
    }
}

void String::append(const String& other)
{
    if(other._Data[0]!= '\0')
    {
        int len = other._length;
        char* temp = new char[_length+1];
        strcpy(temp, _Data);

        delete[] _Data;
        _Data = new char[_length + len + 1];
        
        strcpy(_Data, temp);
        strcpy(_Data+_length, other._Data);
        _length += len;
        *(_Data + _length)='\0';
    }
}

String& String::operator=(const String &other)
{
    if(this == &other)
    {
        return *this;
    }

    delete[] _Data;
    if(other._Data[0] == '\0')
    {
        this->_Data = NULL;
        this->_length = 0;
    }
    else
    {
        _Data = new char[other._length + 1];
        this->_length = other._length;
        strcpy(_Data, other._Data);
    }
    return *this;
}

char& String::operator[](unsigned int index)
{
    if(index>=0 && index<=this->_length-1)
    {
        return _Data[index];
    }
    //TODO:
}

String& String::operator+=(const String& other)
{
    if(other._Data[0] != '\0')
    {
        this->append(other);
    }
    return *this;
}

String& String::operator+=(const char* str)
{
    if(str)
    {
        this->append(str);
    }
    return *this;
}

/*
bool String::operator==(const String& right) const
{
    if(this == &right)
    {
        return true;
    }
    if(this->_length != right._length)
    {
        return false;
    }
    return strcmp(this->_Data, right._Data)?false:true;
}

bool String::operator!=(const String& right) const
{
    return !(this->operator ==(right));
}
*/

const char* String:: c_str() const
{
    return this->_Data;
}

String::operator const char*() const
{
    return this->_Data;
}

String operator+(const String& left, const String& right)
{
    String newStr;
    newStr.append(left);
    newStr.append(right);
    return newStr;
}

String operator+(const char* left, const String& right)
{
    String newStr;
    newStr.append(left);
    newStr.append(right);
    return newStr;
}

String operator+(const String& left, const char* right)
{
    String newStr;
    newStr.append(left);
    newStr.append(right);
    return newStr;
}

bool operator==(const String& left, const String& right)
{
    if(&left == &right)
    {
        return true;
    }
    if(left.length() != right.length())
    {
        return false;
    }
    return strcmp(left.c_str(), right.c_str())?false:true;
}

bool operator!=(const String& left, const String& right)
{
    return !(left == right);
}

ostream& operator<<(ostream& ostr, const String& str)
{
    ostr<<str.c_str();
    return ostr;
}

istream& operator>>(istream& istr, String& str)
{
    std::string temp;
    //Here has the some problem with std::cin, that is the input string can't have space. 
    istr >> temp; 
    str = temp.c_str();

    return istr;
}





mainFile.cpp
#include <iostream>
#include <string>
#include "SelfString.h"

using std::cout;
using std::endl;
using std::cin;

int main()
{   
    //Unit Test for: Constructor, Assignment operator, Copy Constructor.
    String str("I love C++.");
    cout<<"1. Test for Constructor, should output: I love C++.: "<<str<<endl;
    String str1;
    str1 = "Do you like it?";
    cout<<"2. Test for Construcor, should output: Do you like it?: "<<str1<<endl;
    String str2(str);
    cout<<"3. Test for copy Construcor,should output: I love C++.:"<<str2<<endl;
    str1 = str2;
    cout<<"4. Test for Assignment operator, should output: I love C++.:"<<str1<<endl;

    //Unit Test for: istream& operator>>(istream& istr, String& str);
    String str3;
    cout<<"Please say something(no space) to the client, hit Enter to end: ";
    cin>>str3;
    cout<<"5. Test for operator>>, should same with what you input:"<<str3<<endl;

    //Unit Test for: (1)void append(const char* str); (2)void append(const String& other);
    String str4 = "1234";
    String str5 = "1000";
    str4.append("5678");
    cout<<"6. Test for append(const char* str), should output: 12345678:"<<str4<<endl;
    str4.append(str5);
    cout<<"7. Test for append(const String& other), should output: 123456781000:"<<str4<<endl;

    //Unit Test for: operator const char*();
    String myName("FuQiang");
    int cmp_should_less_than_zero = strcmp(myName, "Walle");
    cout<<"Implicit to convert the String to const char*,"; 
    cout<<"so strcmp() can accept the String as parameter.";
    cout<<"Should return value less than zero:"<< cmp_should_less_than_zero<<endl;
    int cmp_should_EQ_with_zero = strcmp(myName, "FuQiang");
    cout<<"Should return value EQ with zero:" << cmp_should_EQ_with_zero<<endl;
    
    //Unit Test for: operator+
    String one = "One";
    String two = "Two";
    String Str5 = one + two;
    cout<<"8. Test for operator+, should output: OneTwo:"<<Str5<<endl;
    String Str6 = "Three" + one;
    cout<<"9. Test for operator+, should output:ThreeOne:"<<Str6<<endl;
    String Str7 = two + "Four";
    cout<<"10. Test for operator+, should output TwoFour:"<<Str7<<endl;

    //Unit Test for: void swap(String& other);
    String swapLeft("Left");
    String swapRight("Right");
    swapLeft.swap(swapRight);
    cout<<"11. Test for swap(String& other), should output: Right left:"<<swapLeft<<" "<<swapRight<<endl;
    
    //Unit Test for: operator+=
    String plusEqualOne("one");
    String sum;
    sum += plusEqualOne;
    cout<<"12. Test for operator+=, should output: one:"<<sum<<endl;
    sum += "Two";
    cout<<"13. Test for operator+=, should output: oneTwo:"<<sum<<endl;
    
    //Unit Test for: operator== and operator!=
    String equal1 = "fuqiang";
    String equal2 = "fuqiang";
    cout<<"14. Test for operator==, should output 1:"<<(equal1 == equal2) <<endl;
    String equal3 = "Fuqiang";
    cout<<"15. Test for operator==, should output 0:"<<(equal1 == equal3) <<endl;
    cout<<"16. Test for operator!=, should output 1:"<<(equal1 != equal3) <<endl;
    cout<<"17. Test for operator!=, should output 0:"<<(equal1 != equal2) <<endl;
    
    system("PAUSE");
}



Some items I need to spend some time to consider:
1. How to elegantly  catch and handle the exception of applying resources on heap (new operator).


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值