How to create a custom String class in C++ with basic functionalities

In this article, we will create our custom string class which will have the same functionality as the existing string class.

The string class has the following basic functionalities:

  1. Constructor with no arguments: This allocates the storage for the string object in the heap and assign the value as a NULL character.
  2. Constructor with only one argument : It accepts a pointer to a character or we can say if we pass an array of characters, accepts the pointer to the first character in the array then the constructor of the String class allocates the storage on the heap memory of the same size as of the passed array and copies the contents of the array to that allocated memory in heap. It copies the contents using the strcpy() function declared in cstring library.
    Before doing the above operation it checks that if the argument passed is a NULL pointer then it behaves as a constructor with no arguments.
  3. Copy Constructor: It is called when any object created of the same type from an already created object then it performs a deep copy. It allocates new space on the heap for the object that is to be created and copies the contents of the passed object(that is passed as a reference).
  4. Move Constructor: It is typically called when an object is initialized(by direct-initialization or copy-initialization) from rvalue of the same type. It accepts a reference to an rvalue of an object of the type of custom string class.

Below is the implementation of the above methods using custom string class Mystring:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to illustrate the
// above discussed functionality
#include <cstring>
#include <iostream>
using namespace std;
  
// Custom string class
class Mystring {
  
    // Initialise the char array
    char* str;
  
public:
    // No arguments Constructor
    Mystring();
  
    // Constructor with 1 arguments
    Mystring(char* val);
  
    // Copy Constructor
    Mystring(const Mystring& source);
  
    // Move Constructor
    Mystring(Mystring&& source);
  
    // Destructor
    ~Mystring() { delete str; }
};
  
// Function to illustrate Constructor
// with no arguments
Mystring::Mystring()
    : str{ nullptr }
{
    str = new char[1];
    str[0] = '\0';
}
  
// Function to illustrate Constructor
// with one arguments
Mystring::Mystring(char* val)
{
    if (val == nullptr) {
        str = new char[1];
        str[0] = '\0';
    }
  
    else {
  
        str = new char[strlen(val) + 1];
  
        // Copy character of val[]
        // using strcpy
        strcpy(str, val);
  
        cout << "The string passed is: "
             << str << endl;
    }
}
  
// Function to illustrate
// Copy Constructor
Mystring::Mystring(const Mystring& source)
{
    str = new char[strlen(source.str) + 1];
    strcpy(str, source.str);
}
  
// Function to illustrate
// Move Constructor
Mystring::Mystring(Mystring&& source)
{
    str = source.str;
    source.str = nullptr;
}
  
// Driver Code
int main()
{
    // Constructor with no arguments
    Mystring a;
  
    // Convert string literal to
    // char array
    char temp[] = "Hello";
  
    // Constructor with one argument
    Mystring b{ temp };
  
    // Copy constructor
    Mystring c{ a };
  
    char temp1[] = "World";
  
    // One arg constructor called,
    // then the move constructor
    Mystring d{ Mystring{ temp } };
    return 0;
}

chevron_right


Output:

The string passed is: Hello
The string passed is: Hello

Some more functionalities of string class:



  1. pop_back(): Removes the last element from the Mystring object.
  2. push_back(char ch): Accepts a character as an argument and adds it to the end of the Mystring object.
  3. length(): Returns the length of the mystring.
  4. copy(): It copies the mystring object to a character array from a given position(pos) and a specific length(len).
  5. swap(): It swaps the two Mystring objects.
  6. Concatenate two strings using overloading the ‘+’ operator: Allows us to concatenate two strings.

Below is the program to illustrate the above-discussed functionality:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to illustrate the
// above functionalities
#include <cstring>
#include <iostream>
using namespace std;
  
// Class Mystring
class Mystring {
  
    // Prototype for stream insertion
    friend ostream&
    operator<<(
        ostream& os,
        const Mystring& obj);
  
    // Prototype for stream extraction
    friend istream& operator>>(
        istream& is,
        Mystring& obj);
  
    // Prototype for '+'
    // operator overloading
    friend Mystring operator+(
        const Mystring& lhs,
        const Mystring& rhs);
    char* str;
  
public:
    // No arguments constructor
    Mystring();
  
    // pop_back() function
    void pop_bk();
  
    // push_back() function
    void push_bk(char a);
  
    // To get the length
    int get_length();
  
    // Function to copy the string
    // of length len from position pos
    void cpy(char s[], int len, int pos);
  
    // Swap strings function
    void swp(Mystring& rhs);
  
    // Constructor with 1 arguments
    Mystring(char* val);
  
    // Copy Constructor
    Mystring(const Mystring& source);
  
    // Move Constructor
    Mystring(Mystring&& source);
  
    // Overloading the assignment
    // operator
    Mystring& operator=(
        const Mystring& rhs);
  
    // Destructor
    ~Mystring() { delete str; }
};
  
// Overloading the assignment operator
Mystring& Mystring::operator=(
    const Mystring& rhs)
{
    if (this == &rhs)
        return *this;
    delete[] str;
    str = new char[strlen(rhs.str) + 1];
    strcpy(str, rhs.str);
    return *this;
}
  
// Overloading the plus operator
Mystring operator+(const Mystring& lhs,
                   const Mystring& rhs)
{
    int length = strlen(lhs.str)
                 + strlen(rhs.str);
  
    char* buff = new char[length + 1];
  
    // Copy the strings to buff[]
    strcpy(buff, lhs.str);
    strcat(buff, rhs.str);
  
    // String temp
    Mystring temp{ buff };
  
    // delete the buff[]
    delete[] buff;
  
    // Return the concatenated string
    return temp;
}
// Overloading the stream
// extraction operator
istream& operator>>(istream& is,
                    Mystring& obj)
{
    char* buff = new char[1000];
    is >> buff;
    obj = Mystring{ buff };
    delete[] buff;
    return is;
}
  
// Overloading the stream
// insertion operator
ostream& operator<<(ostream& os,
                    const Mystring& obj)
{
    os << obj.str;
    return os;
}
  
// Function for swapping string
void Mystring::swp(Mystring& rhs)
{
    Mystring temp{ rhs };
    rhs = *this;
    *this = temp;
}
  
// Function to copy the string
void Mystring::cpy(char s[], int len,
                   int pos)
{
    for (int i = 0; i < len; i++) {
        s[i] = str[pos + i];
    }
    s[len] = '\0';
}
  
// Function to implement push_bk
void Mystring::push_bk(char a)
{
    // Find length of string
    int length = strlen(str);
  
    char* buff = new char[length + 2];
  
    // Copy character from str
    // to buff[]
    for (int i = 0; i < length; i++) {
        buff[i] = str[i];
    }
    buff[length] = a;
    buff[length + 1] = '\0';
  
    // Assign the new string with
    // char a to string str
    *this = Mystring{ buff };
  
    // Delete the temp buff[]
    delete[] buff;
}
  
// Function to implement pop_bk
void Mystring::pop_bk()
{
    int length = strlen(str);
    char* buff = new char[length];
  
    // Copy character from str
    // to buff[]
    for (int i = 0; i < length - 1; i++)
        buff[i] = str[i];
    buff[length] = '\0';
  
    // Assign the new string with
    // char a to string str
    *this = Mystring{ buff };
  
    // delete the buff[]
    delete[] buff;
}
  
// Function to implement get_length
int Mystring::get_length()
{
    return strlen(str);
}
  
// Function to illustrate Constructor
// with no arguments
Mystring::Mystring()
    : str{ nullptr }
{
    str = new char[1];
    str[0] = '\0';
}
  
// Function to illustrate Constructor
// with one arguments
Mystring::Mystring(char* val)
{
    if (val == nullptr) {
        str = new char[1];
        str[0] = '\0';
    }
  
    else {
  
        str = new char[strlen(val) + 1];
  
        // Copy character of val[]
        // using strcpy
        strcpy(str, val);
    }
}
  
// Function to illustrate
// Copy Constructor
Mystring::Mystring(const Mystring& source)
{
    str = new char[strlen(source.str) + 1];
    strcpy(str, source.str);
}
  
// Function to illustrate
// Move Constructor
Mystring::Mystring(Mystring&& source)
{
    str = source.str;
    source.str = nullptr;
}
  
// Driver Code
int main()
{
    // Constructor with no arguments
    Mystring a;
  
    // Convert string literal to
    // char array
    char temp[] = "Hello";
  
    // Constructor with one argument
    Mystring b{ temp };
  
    // Copy constructor
    Mystring c{ a };
  
    char temp1[] = "World";
  
    // One arg constructor called,
    // then the move constructor
    Mystring d{ Mystring{ temp } };
  
    // Remove last character from
    // Mystring b
    b.pop_bk();
  
    // Print string b
    cout << "Mystring b: "
         << b << endl;
  
    // Append last character from
    // Mystring b
    b.push_bk('o');
  
    // Print string b
    cout << "Mystring b: "
         << b << endl;
  
    // Print length of string b
    cout << "Length of Mystring b: "
         << b << endl;
  
    char arr[80];
  
    // Copy string b chars from
    // length 0 to 3
    b.cpy(arr, 3, 0);
  
    // Print string arr
    cout << "arr is: "
         << arr << endl;
  
    // Swap d and b
    d.swp(b);
  
    // Print d and b
    cout << d << " "
         << b << endl;
  
    // Concatenate b and b with
    // overloading '+' operator
    d = b + b;
  
    // Print string d
    cout << "string d: "
         << d << endl;
  
    return 0;
}

chevron_right


Output:

Mystring b: Hell
Mystring b: Hello
Length of Mystring b: Hello
arr is: Hel
Hello Hello
string d: HelloHello

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.