Simple implementation of C++string class

In the C + + standard library, the string class encapsulates the string in the form of type, which makes it like a container for storing characters and contains many processing operations of character sequences.

In this paper, the following functions are implemented preliminarily:

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

class Mystring;

ostream& operator << (ostream& os,const Mystring& s);
istream& operator >> (istream& in,const Mystring& s);

class Mystring{
public:
    Mystring();
    Mystring(const char *s);
    Mystring(const Mystring &other);
    ~Mystring();
    Mystring& operator = (const Mystring &);
    Mystring& operator = (const char *);
    Mystring operator + (const Mystring & other);
    friend ostream& operator << (ostream& os,const Mystring & s);
    friend istream& operator >> (istream& in,const Mystring & s);
    bool operator == (const Mystring &);
    int size() const;
    int length() const;
    const char* getstring() const;
    char & operator [] (const int index);
private:
    char *str;
    int len;
};

Let's see the specific implementation:

#include<iostream>
#include<string.h>
#include"Mystring.h"

using namespace std;

Mystring::Mystring(){
    str = new char[1];
    str[0] = '\0';
    len = 0;
}
Mystring::Mystring(const char* p){
    if(p){
        len = strlen(p);
        str = new char [len+1];
        strcpy(str,p);
    }
    else{
        Mystring();
    }
}
Mystring::Mystring(const Mystring& other){
    len = other.length();
    str = new char[len+1];
    strcpy(str,other.str);
}
int Mystring::length() const{
    return len;
}
int Mystring::size() const{
    return len;
}
Mystring& Mystring::operator=(const Mystring& other){
    if(&other == this)
        return *this;
    delete [] str;
    len = other.length();
    str = new char[len + 1];
    strcpy(str,other.str);
    return *this;
}
Mystring& Mystring::operator=(const char* p){
    delete [] str;
    len = strlen(p);
    str = new char [len + 1];
    strcpy(str,p);
    return *this;
}
Mystring Mystring::operator+(const Mystring & other){
    int size = this->length() + other.length();
    char* s = (char*)malloc(sizeof(char)*size);
    int i = 0;
    int j = 0;
    for(i = 0;i < this->length();++i){
        s[i] = this->str[i];
    }
    for(j = 0;j < other.length(); ++j){
        s[i+j] = other.str[j];
    }
    s[i+j] = '\0';
    Mystring tmp;
    tmp.str = s;
    return tmp;
}
ostream& operator << (ostream& os,const Mystring & s){
    os << s.getstring();
    return os;
}
istream& operator >> (istream& in,const Mystring & s){
    in >> s.str;
    return in;
}
bool Mystring::operator == (const Mystring & other){
    if(this->len != other.len)
        return false;
    else{
        for(int i = 0;i < len; ++i){
            if(str[i]!=other.str[i])
                return false;
        }
        return true;
    }
}
const char* Mystring::getstring() const{
    return this->str;//Return the first pointer of the string directly
}
Mystring::~Mystring(){
    delete [] str;
    len = 0;
}
char & Mystring::operator[](const int index){
    if(index>len){
        cout<<"out of boundary!"<<endl;
        cout<<"The last char is:"<<endl;
        return str[len-1];
    }
    else{
        return str[index-1];
    }
}

Test documents:

#include<iostream>
#include<string.h>
#include"Mystring.h"

using namespace std;

int main(){
    Mystring a;
    cout << "Default constructor implementation initialization" << endl;
    cout << "string a = " << a << endl;    
    cout << "Length = " << a.length() << endl << endl;
             
    Mystring b("123456");
    cout << "Normal constructor implementation initialization" << endl;
    cout << "string b = " << b << endl;
    cout << "Length = " << b.length() << endl << endl;
                             
    Mystring c(b);
    cout << "Copy constructor implementation initialization" << endl;
    cout << "string c = " << c << endl;
    cout << "Length = " << c.length() << endl << endl;
                                    
    Mystring d = b;    //The default constructor will not be called again for initialization 
    cout << "call =(object) Implementation assignment" << endl;
    cout << "string d = " << d << endl;
    cout << "Length = " << d.length() << endl << endl;
                                                             
    Mystring e = "00000000";
    cout << "call =(Dynamic pointer) Implementation assignment" << endl;
    cout << "string d = " << e << endl;
    cout << "Length = " << e.length() << endl << endl;

    Mystring f = "abcdefghijklmn";
    char str = f[5];
    cout << "call []  Implement index positioning output" << endl;
    cout<<"f[5]:"<<str<<endl;

    Mystring g = b + e;
    cout << "Add operation" << endl;
    cout<<"b + e ="<< g <<endl;

    cout << "call == To judge d and b Are they equal?" << endl;
    if(d == b)
        cout<<"string d == string b"<<endl;
    else
        cout<<"string d != string b"<<endl;

    Mystring h;
    cout << "Enter a string: To verify >> operator" << endl;
    cin>>h;
    cout<< h <<endl;

    return 0;
}

There is a serious problem in writing:

Functions with overloaded operators, such as "+", can be written as member functions of a class, but output operators "< are not allowed!!! Think for a long time, suddenly realize!!

Simply, the left and right parameters of < are the caller and the callee. If you define it as a member function, you will add this pointer to three parameters. The operator only needs two parameters!! So the compiler can't bind.

If you write this function outside the class:

ostream& operator<<(ostream& os, const classType& obj);

Then in the class to declare it as a friend function to solve this problem perfectly!

Posted by tomlei on Wed, 27 Nov 2019 06:34:46 -0800