Returning an object from a method - Problem when creating my own string class

This is a discussion on Returning an object from a method - Problem when creating my own string class within the C++ Programming forums, part of the General Programming Boards category; Hello, I am a beginning level C++ programmer. I have an assignment in which I need to create my own ...

  1. #1
    Registered User
    Join Date
    Sep 2001
    Posts
    7

    Returning an object from a method - Problem when creating my own string class

    Hello,

    I am a beginning level C++ programmer. I have an assignment in which I need to create my own basic string class. There are several methods that I need to support, such as leftTrim, righttrim, toLowerCase, toUpperCase. I have been able to handle all of those, but I am now trying to code a substring class.

    The prototype is defined as substring(int start, int end), the method should return a new string that is a substring of the string object that the mehod is being used against.

    The example that I was able to get from my teacher is:

    ~~~~~~~~~~

    //my class is called mystring

    //initialize the variable temp
    mystring temp (“hello”);

    //return the value of substring to temp2, the value of the string would be “hel”
    mystring temp2 = temp.substring(0,2);

    ~~~~~~~~~~~

    The problem that I think I am having (I’m not completely sure) is trying to return an object of mystring from the substring method. My thought was that I would need to have an object of type mystring defined within the class mystring. See the class definition below) I would then modify that object to contain the substring and return that object.

    First I tried declaring the variable as - mystring m_mystringTemp -, but the compiler complained:

    error C2460: 'm_mystringTemp' : uses 'mystring', which is being defined
    c:\cis569 _obj_or_prog_with_c++\assn3\mystring.h(19) : see declaration of 'mystring'

    I then changed it to a pointer and did not receive this error. But I get a run time error when I execute the program. When I step thru the program, I see that is calling a constructor at the time that it is returning the value from the substring method and that is where the error occurs. But I am not sure why the constructor is being called or what to do next.

    The code for the substring method is incomplete, I was just starting when I ran into this issue.

    Below I will include the mystring,h file and the mystring.cpp file in case it is needed. I am not looking for someone to write the code, just help me understand what I am missing or doing wrong.

    Thanks for any help,
    Paul

    ################################################## ###



    Mystring.h


    #include <iostream>
    using namespace std;

    class mystring
    {
    public:
    mystring();
    mystring(char* charArray);
    mystring(const mystring &string);
    virtual ~mystring();

    char charAt(int index);
    bool concat(mystring string);
    mystring substring(int start, int end);
    void toLowerCase(void);
    void toUpperCase(void);
    void trim(void);
    void rightTrim(void);
    void leftTrim(void);

    char *display(void);



    private:
    char *m_buff; //pointer to a character array
    char *m_buffTemp;
    int counter1;
    int counter2;
    mystring *m_mystringTemp;


    };


    mystring.cpp


    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////
    //Default constructor - allocate a new string containing no characters
    mystring::mystring()
    {
    cout << "Inside the mystring() Constructor\n";
    m_buff = (char *) malloc( sizeof(0));
    m_buff= NULL;


    //******************
    m_buffTemp = (char *) malloc( sizeof(0));
    m_buffTemp = NULL;
    //******************


    cout << "Leavingthe mystring()\n\n";

    }

    ///////////////////////////////////////////////////////////////////////
    //Constructor Two - Convert the array of characters
    mystring::mystring(char *charArray)
    {
    cout << "Inside the mystring(char *charArray) Constructor\n";

    //allocate memory
    //m_buff = (char *) malloc( sizeof(charArray) +1);
    m_buff = (char *) malloc( strlen(charArray) +1);


    //copy charArray into m_buff variable
    strcpy(m_buff,charArray);

    //add the NULL value on end
    m_buff[strlen(m_buff)] = '\0';


    //******************
    m_buffTemp = (char *) malloc( sizeof(0));
    m_buffTemp = NULL;
    //******************

    cout << "m_buff =" << m_buff << endl;
    cout << "Leaving mystring(char *charArray) constructor\n\n";

    }



    ///////////////////////////////////////////////////////////////////////
    //Constructor Four - Allocate a new string that contains the same sequence of characters
    // as the string argument
    //Question -
    mystring::mystring(const mystring &string)
    {
    cout << "Inside the mystring(mystring string) Constructor\n";

    //allocate memory
    m_buff = (char *) malloc( strlen(string.m_buff) +1);

    //copy string char* data into this new string object
    strcpy(m_buff, string.m_buff);


    //******************
    m_buffTemp = (char *) malloc( sizeof(0));
    m_buffTemp = NULL;
    //******************


    cout << "Leaving mystring(const mystring &string) constructor\n\n";
    }


    ////////////////////////////////////////////////////////////////////////
    // Destructor - Destructor - Destructor

    mystring::~mystring()
    {

    if (m_buff !=NULL)
    delete[]m_buff;

    }



    ////////////////////////////////////////////////////////////////////////
    // charAt -- charAt -- charAt
    // Returns the character at the specified index
    // Return -1 if the index is beyond the length of string or the string is NULL
    char mystring::charAt(int index)
    {
    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return(-1);
    }

    cout<< "In charAt ";
    cout<< "Buff -" << m_buff << "-" <<endl;

    if(index > strlen(m_buff) || index < 0)
    return(-1);
    else
    return(m_buff[index]);
    }


    //////////////////////////////////////////////////////////////////////////
    // trim -- trim - trim
    // Removes white space from both ends of this string

    void mystring::trim(void)
    {
    cout << "Inside trim\n";

    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return;
    }

    counter1=0;
    counter2=strlen(m_buff);

    //allocate memory for temporary buffer
    m_buffTemp = (char *) malloc( strlen(m_buff) +1);

    //skip all blanks at beginning and get index value
    while(m_buff[counter1]==' ')
    {
    counter1++;
    }

    cout << "Counter 1 = " << counter1 << endl;

    //skip all blanks at end and get index value
    while(m_buff[counter2--]==' ')
    {
    counter2--;
    }
    cout << "Counter 2 = "<< counter2 << endl;

    //copy the trimmed text to a temporary string and add NULL
    strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
    m_buffTemp[counter2 - counter1] = '\0';
    cout << "Trimmed text = -" << m_buffTemp << "-"<<endl;

    //copy the temporary string back over original
    strcpy(m_buff, m_buffTemp);
    cout << "Original text now trimmed -" << m_buff << "-" <<endl;

    }



    //////////////////////////////////////////////////////////////////////////
    // rightTrim -- rightTrim - rightTrim
    // Removes white space from right end of this string

    void mystring::rightTrim(void)
    {

    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return;
    }

    cout << "Inside rightTrim - Text -" << m_buff << "-" << "\n";

    counter1=0;
    counter2=strlen(m_buff);

    //allocate memory for temporary buffer
    m_buffTemp = (char *) malloc( strlen(m_buff) +1);

    //skip all blanks at end and get index value
    while(m_buff[counter2--]==' ')
    {
    counter2--;
    }
    cout << "Counter 2 = "<< counter2 << endl;

    //copy the trimmed text to a temporary string and add NULL
    strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
    m_buffTemp[counter2 - counter1] = '\0';
    cout << "RightTrimmed text = -"<< m_buffTemp << "-" << endl;

    //copy the temporary string back over original
    strcpy(m_buff, m_buffTemp);
    cout << "Original text now RightTrimmed -" << m_buff << "-" <<endl;


    }


    //////////////////////////////////////////////////////////////////////////
    // leftTrim -- leftTrim - leftTrim
    // Removes white space from left end of this string

    void mystring::leftTrim(void)
    {

    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return;
    }

    cout << "Inside leftTrim - Text -" << m_buff << "-" << "\n";

    counter1=0;
    counter2=strlen(m_buff);

    //allocate memory for temporary buffer
    m_buffTemp = (char *) malloc( strlen(m_buff) +1);

    //skip all blanks at beginning and get index value
    while(m_buff[counter1]==' ')
    {
    counter1++;
    }

    cout << "Counter 1 = " << counter1 << endl;

    //copy the trimmed text to a temporary string and add NULL
    strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
    m_buffTemp[counter2 - counter1] = '\0';
    cout << "LeftTrimmed text = -" << m_buffTemp << "-"<<endl;

    //copy the temporary string back over original
    strcpy(m_buff, m_buffTemp);
    cout << "Original text now LeftTrimmed -" << m_buff << "-" <<endl;

    }



    //////////////////////////////////////////////////////////////////////////
    // toLowerCase -- toLowerCase -- toLowerCase
    // Converts this string to lowercase

    void mystring::toLowerCase(void)
    {
    cout << "Inside toLowerCase\n";

    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return;
    }

    counter1=strlen(m_buff);
    counter2 = 0;

    //convert all to lowercase
    while(m_buff[counter2]!='\0' || counter2 < counter1)
    {

    m_buff[counter2]=tolower(m_buff[counter2]);
    counter2++;
    }

    cout << "Original text now tolower -" << m_buff << "-" <<endl;

    }


    //////////////////////////////////////////////////////////////////////////
    // toUpperCase -- toUpperCase -- toUpperCase
    // Converts this string to uppercase

    void mystring::toUpperCase(void)
    {
    cout << "Inside toUpperCase\n";

    //if the string is empty return to calling method
    if( m_buff == NULL )
    {
    return;
    }

    counter1=strlen(m_buff);
    counter2 = 0;

    //convert all to uppercase
    while(m_buff[counter2]!='\0' || counter2 < counter1)
    {

    m_buff[counter2]=toupper(m_buff[counter2]);
    counter2++;
    }

    cout << "Original text now toupper -" << m_buff << "-" <<endl;

    }

    //////////////////////////////////////////////////////////////////////////
    // concat -- concat - concat
    // Concatenates the specified string to the end of this string
    // NULL - if the object string m_buff is NULL, it will have memory allocated
    // for the size of the concated string and then that concated string
    // string.m_buff will be copied over. The first check is if both
    // strings are NULL, if so then return a 0 value.
    // Return a value of 1 if successfull
    // QUESTION - Code for an empty string - test it out
    bool mystring::concat(mystring string)
    {
    cout << "Inside concat\n";

    //Test if string to concat is NULL
    if(string.m_buff == NULL)
    return(0);

    //Test if the m_buff string is NULL, if so allocate mem and copy over the
    // string to concat and return a true value
    if(m_buff == NULL)
    {
    m_buff = (char *) malloc( strlen(string.m_buff) +1);
    strcpy(m_buff, string.m_buff);
    return(1);
    }


    //**Logic below will get used if neither string is NULL


    //allocate memory for temporary buffer that is enough for both strings
    m_buffTemp = (char *) malloc( strlen(m_buff) + strlen(string.m_buff) +1);


    //copy over this objects string and then concat the other string into temp
    strcpy(m_buffTemp, m_buff);
    strcat(m_buffTemp, string.m_buff);
    cout << "The concat string in buffTemp -" <<m_buffTemp <<"-\n";

    //delete the m_buff, re-allocate mem and copy the temporary back over it
    free(m_buff);
    m_buff = (char *) malloc( strlen(m_buffTemp) +1);
    strcpy(m_buff, m_buffTemp);
    cout << "The concat string in m_buff in concat -" <<m_buffTemp <<"-\n";

    //delete the m_buffTemp and set to NULL, not sure if need to set to NULL
    // need to see if free does this for you.
    free(m_buffTemp);
    m_buffTemp = NULL;

    return(1);

    }



    //////////////////////////////////////////////////////////////////////////
    // subString -- subString -- subString
    // Returns a new string that is a substring of thsi string (start at
    // int1 and end at int2
    // QUESTION - Code for an empty string - test it out
    mystring mystring::substring(int start, int end)
    {

    //check that the start value is valid, if not then leave method
    if(start < 0 || start > strlen(m_buff))
    return(*m_mystringTemp);


    return(*m_mystringTemp);

    //check that end value is valid, if not then reassign a value that
    // is equal to the length of the string that this method is acting on
    // This will allow the method to continue without error


    //copy the substring value into the temporary string class and then return it




    }

    //////////////////////////////////////////////////////////////////////////
    // display
    // Displays the m_buff data
    char *mystring::display(void)
    {
    if(m_buff == NULL)
    return (NULL);
    else
    return(m_buff);
    }

  2. #2
    zen
    zen is offline
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    You could read the char's to -> from into a temporary char array within your mystring method and just return the array. As you've defined a conversion constructor that takes a char*, as long as you are constructing a new object from the return value of mystring as in the example given by your teacher and not assigning (you'd need to overload operator=), a new string object based on the substring should be created.
    zen

  3. #3
    Registered User matheo917's Avatar
    Join Date
    Sep 2001
    Posts
    279

    Lightbulb

    Zen is right...... the compiler doesn't know how to assign one object to the other.... i am pertaining to the object of your class....if you have already covered (in your school) operator overloading then you would have to overload the (operator=) so it knows how to add to objects of a user-defined class... however if you haven't yet covered operator overloading i suggest using attributes of a <string> header file....

    #include <string>
    using namespace std;

    and define a string instead of an array of characters....

    string MyLittleString = "i am a string";

    and not an array of characters

    char ManyCharacters[80] = "i am a bunch of characters...";

    hope that helps...

    Regards,
    matheo917

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    7
    Thanks for your help on this problem ...

    PC

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem in pass a variable to a class
    By nima_pw in forum C# Programming
    Replies: 3
    Last Post: 06-09-2009, 07:30 AM
  2. A question about constructors...
    By Wolve in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2005, 04:24 PM
  3. problem with sending files to a class method..
    By utoots in forum C++ Programming
    Replies: 5
    Last Post: 04-02-2003, 12:38 AM
  4. returning a temp. object problem
    By nextus in forum C++ Programming
    Replies: 1
    Last Post: 01-18-2003, 08:12 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21