Thread: Problem with implementation string class

  1. #1
    Registered User
    Join Date
    Mar 2020
    Posts
    4

    Problem with implementation string class

    Hello
    I've got a task to write a simple prototype of string class, but unfortunately I have no idea how to do some things.
    This is how it looks now:

    Code:
    #include <iostream>
    
    
    class myString {
    public:
        int length;
        char* content;
        myString();
        myString(const char*);
        ~myString();
    };
    
    
    myString::myString() {
        content = 0;
        length = 0;
    }
    
    
    myString::~myString() {
        delete[] content;
    }
    
    
    int stringLength(const char* number) {
        int c = 0;
        while (*(number++)) c++;
        return c;
    }
    
    
    myString::myString(const char* number) {
        length = stringLength(number);
        content = new char[length + 1];
        for (int k = 0; k < length; k++)
            content[k] = number[k];
        
        content[length] = '\0';
    }
    
    
    std::ostream& operator<<(std::ostream& out, const myString& towrite) {
        out << towrite.content;
        return out;
    }
    
    int main()
    {
        myString name = "ezample";
        std::cout << name;
        std::cout << name[0]; //here not working
        return 0;
    }
    My problem is in main() function - I thought that accessing string via indexes is possible, but it's not. And, unfortunately, I have no idea what to do with that. This is char * array, so I thought that there is no problem with printing particular characters. Maybe there is a simple explanation for this?

    Also, I wanted to implement std::istream &operator for this class, it works, but I don't know if it's okay, so if anyone could check it I'd be grateful.
    Code:
    std::istream& operator>>(std::istream& in, const myString& toload) {
        in >> toload.content;
        return in;
    }
    Thanks for any advice and help.

    The error that appears in main: Error (active) : E0349 no operator "[]" matches these operands. Operands types are myString [ int ]
    Last edited by obeeey; 03-04-2020 at 02:18 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by obeeey
    My problem is in main() function - I thought that accessing string via indexes is possible, but it's not. And, unfortunately, I have no idea what to do with that. This is char * array, so I thought that there is no problem with printing particular characters. Maybe there is a simple explanation for this?
    You need to overload operator[] for your myString class. There should be two overloads: a non-const version and a const version.

    A few other things to note:
    • Right now your notion of an "empty string" is an invalid string because you set content to be a null pointer, yet make no provision to check for null pointers when you say, print a string. This is not necessarily wrong, but it is likely that other programmers expect an "empty string" to be a valid string of zero length instead.
    • You need to implement the copy constructor and copy assigment operator too. If not, your myString objects won't behave as expected when you pass copies of them around, resulting in double deletion errors.
    • Don't worry about it for now as it is likely beyond the scope of your learning task, but at some point you may wish to implement the move constructor and move assignment operator for your myString class as practice.


    Quote Originally Posted by obeeey
    Also, I wanted to implement std::istream &operator for this class, it works, but I don't know if it's okay, so if anyone could check it I'd be grateful.
    Unfortunately it won't work unless toload happens to be already large enough: you need to set the length and allocate space just like you did in the constructor that takes a pointer to char argument. Also, toload needs to be a non-const reference instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Sir Galahad's Avatar
    Join Date
    Nov 2016
    Location
    The Round Table
    Posts
    277
    Code:
    char& myString::operator[](size_t index)
    {
     return content[index];
    }
    
    const char& myString::operator[](size_t index) const
    {
     return content[index];
    }
    Last edited by Sir Galahad; 03-04-2020 at 02:29 PM.

  4. #4
    Registered User
    Join Date
    Mar 2020
    Posts
    4
    Thank you @laserlight for your deep answer, it's really nice to know exactly what's wrong there. I wrote copy operator and copy assignment, this is how it looks:
    Code:
    void myString::copy(const myString &source)
    {
        length = source.length;
        content = new char[length + 1];
        for (int k = 0; k < length; k++)
            content[k] = source.content[k];
    }
    
    
    myString &myString::operator =(const myString &source)
    {
        copy(source);
        return *this;
    }
    Is it enough to not worry about some errors? Also, should I now delete the myString::myString(const char* number) method, where the assingment took place at first?

    also @Sir Galahad thank you for the code with operators, clear and simple

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by obeeey
    I wrote copy operator and copy assignment, this is how it looks:
    Close, but I was talking about the copy constructor, so it should look like this:
    Code:
    myString::myString(const myString &source)
    {
        length = source.length;
        content = new char[length + 1];
        for (int k = 0; k < length; k++)
            content[k] = source.content[k];
        content[length] = '\0';
    }
    Notice that I added the null termination.

    Quote Originally Posted by obeeey
    Is it enough to not worry about some errors?
    The problem now is that the copy assignment operator should not merely overwrite the existing length and content: if the space allocated for content is too small, it needs to expand the dynamic array of char.

    Quote Originally Posted by obeeey
    Also, should I now delete the myString::myString(const char* number) method, where the assingment took place at first?
    Of course not. It is a separate constructor that allows you to construct a myString object from a null terminated string.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Mar 2020
    Posts
    4
    Thank you again for answer. Everything is fine except the assignment operator now.
    It looked like this:
    Code:
    typeString& typeString::operator =(const typeString& source)
    {
        copy(source);
        return *this;
    }
    but now of course there is no copy() function. I'm treading on thin ice right now and I don't want to sound too stupid, but, how to use in this assignment operator copy method? If I don't know the content size, (in my task I have to cin a number with any amount of digits), how to prepare for this?

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by obeeey
    but now of course there is no copy() function. I'm treading on thin ice right now and I don't want to sound too stupid, but, how to use in this assignment operator copy method?
    I suggest doing this the old way: implement a swap member function, then implement the copy assignment operator using the copy constructor, swap, and destructor:
    Code:
    void myString::swap(myString& other)
    {
        // ... swap the lengths and pointers ...
    }
    
    myString& myString::operator=(const myString& other)
    {
        if (this != &other)
        {
            myString temp(other);
            swap(temp);
        }
        return *this;
    }
    Quote Originally Posted by obeeey
    If I don't know the content size, (in my task I have to cin a number with any amount of digits), how to prepare for this?
    This means that you should keep track of both size (number of elements in use) and capacity (number of elements for which storage has been allocated). Read character by character (well, it doesn't have to be literally character by character, but get it to work before you try for complexity) until the terminating condition is reached, storing the characters successively until the size is about to exceed capacity. At that point, you increase the capacity by a factor, allocate the new capacity, and copy over the existing elements to the newly allocated storage, then store the next character and continue looping. Since you want to internally store a null terminated string, remember to null terminate.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Mar 2020
    Posts
    4
    Thank you laserlight. The old way worked! Unless I find other problems, everything works for now. I changed some assumptions about the content size and made it a little easier for me. Thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String class problem
    By Front242 in forum C++ Programming
    Replies: 8
    Last Post: 08-17-2007, 08:18 AM
  2. Implementation of set class in C++
    By hay_man in forum C++ Programming
    Replies: 10
    Last Post: 09-21-2006, 03:33 PM
  3. PLease Help with Class Implementation
    By Dilmerv in forum C++ Programming
    Replies: 13
    Last Post: 04-28-2006, 09:36 AM
  4. Implementation of <vector> class
    By supaben34 in forum C++ Programming
    Replies: 4
    Last Post: 10-13-2002, 09:14 AM
  5. C++ Implementation of a Class
    By leo in forum C++ Programming
    Replies: 3
    Last Post: 09-10-2002, 11:24 AM

Tags for this Thread