• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 925
  • Last Modified:

Overloading operators and methods in string class

I've just read up on overloading operators and methods in the string class.  So far, I was successfully able to do this for the '+' and '=' operators.  However, I'm not sure what other ones I can do.  Is there a list somewhere of string methods/operators?

My codes so far: http://www2.hawaii.edu/~lilyllam/C++/


Any suggestions?  Thank you.
0
luna621
Asked:
luna621
  • 17
  • 9
  • 3
  • +2
4 Solutions
 
luna621Author Commented:
Also, I've created this template:

template <typename A, typename B>
class Pair
{
    public:
          Pair( const A &a, const B &b ):itsA(a), itsB(b){}
          A getA() const { return itsA; }
          B getB() const { return itsB; }

    private:
        A itsA;
        B itsB;
};

template <typename A, typename B>
ostream& operator <<( ostream &o, const Pair<A, B> &p )
{
    o << "<" << p.getA() << ", " << p.getB() << ">";
    return o;
}

-----------------------------------------------------------

I call it in the main() like this:

    Pair<int, string> p1( 10, "ten" );
    cout << p1;           //<-------------------- won't compile

Why doesn't that compile?  I want it to print like how I overloaded the << operator.  Thank you.
0
 
Sys_ProgCommented:
Here is the list of the std::string class

http://cppreference.com/cppstring/


Amit
0
 
Jaime OlivaresSoftware ArchitectCommented:
There are many operators as ==, !=, <, >, <=, >=, [], etc
Have a look to SGI's STL source code at:
http://www.doe-mbi.ucla.edu/~parag/C++_DOCS/STL/string
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
efnCommented:
> Why doesn't that compile?

Maybe you didn't #include <string>?  What is the error message?
0
 
DarrylshCommented:
he's not using std::string, he's using c-strings from string.h (cstring).

To answer your first question here is an excerpt from c++ faq lite:

The only C operators that can't be [overloaded] are . and ?: (and sizeof, which is technically an operator). C++ adds a few of its own operators, most of which can be overloaded except :: and .*.

Here's the link as well as other faqs concerning overloading: http://www.parashift.com/c++-faq-lite/operator-overloading.html

 If you are doing this as a learning experience, that's cool, but if you are trying to make a string class for actual use, then you should consider using the standard c++ string class.  The header is <string>  It already has most of it's operators overloaded.
0
 
DarrylshCommented:
>> Why doesn't that compile?  I want it to print like how I overloaded the << operator.  Thank you.

What errors are you getting?

One thing I noticed, though it won't stop it from compiling is in your ostream overload, your return o.  What you want is to return &o
0
 
luna621Author Commented:
This is the error I get.  I will try it with &o.


Template.cpp(23) : error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
Template.cpp(60) : see reference to function template instantiation 'std::ostream &operator <<<int,std::string>(std::ostream &,const Pair<A,B> &)' being compiled
        with
        [
            A=int,
            B=std::string
        ]
0
 
luna621Author Commented:
Gasp!!  I forgot to #include<string>!!  No wonder it wasn't working!  Okay, that error has been fixed.  I will look at the links everyone provided and post back if I have any questions.  Thank you all :)
0
 
DarrylshCommented:
ignore that last bit, it doesn't need to be &o
0
 
luna621Author Commented:
Ok, I looked at the links and they were very informative.  However, aside from concatenation what else can you do with the overloaded operators?

Updated codes: http://www2.hawaii.edu/~lilyllam/C++/String.cpp
0
 
luna621Author Commented:
This doesn't seem to be working:

ostream& operator <<( ostream &o, const String &str )
{
    o << str;
    return o;
}
0
 
efnCommented:
> ... what else can you do with the overloaded operators?

The language defines a certain number of operators that you can overload.  Since you are writing the functions, you can make them do whatever you want, within the limits of the language.  For example:

String s = "no";
s = s * 3;
//  Now s contains "nonono".

> This doesn't seem to be working:...

You're telling the compiler "To put out a String, put out a String."    If the output operator just calls itself, you will get infinite recursion.  It will probably work better to tell it how to put out a String using other operations that are already available.  For example, "To put out a String, put out the character array inside the String."  To make this work, you will have to make the array public or make the output operator a friend of the String class.
0
 
luna621Author Commented:
I tried these two,


String String::operator *( char *str, int mul )
{
    String temp;
    int i;

    for(i = 0; i <= mul; i++)
    {
        strcpy( temp.string, string );
        strcat( temp.string, str );
    }
    return temp;
}


String String::operator *( String str, int mul )
{
    int i;
    for(i = 0; i <= mul; i++)
    {
        strcpy( string, str.string );
    }
    return *this;
}

...

main()
...

String s = "no";
s = s * 3;




but, these were the errors:


String.cpp(148) : error C2039: '*' : is not a member of 'String'
String.cpp(29) : see declaration of 'String'
String.cpp(155) : error C2248: 'String::string' : cannot access private member declared in class 'String'
String.cpp(30) : see declaration of 'String::string'
String.cpp(29) : see declaration of 'String'
String.cpp(155) : error C2275: 'std::string' : illegal use of this type as an expression
xstring(1562) : see declaration of 'std::string'
String.cpp(156) : error C2248: 'String::string' : cannot access private member declared in class 'String'
String.cpp(30) : see declaration of 'String::string'
String.cpp(29) : see declaration of 'String'
String.cpp(174) : error C2039: '*' : is not a member of 'String'
String.cpp(29) : see declaration of 'String'
String.cpp(179) : error C2275: 'std::string' : illegal use of this type as an expression
xstring(1562) : see declaration of 'std::string'
String.cpp(179) : error C2248: 'String::string' : cannot access private member declared in class 'String'
String.cpp(30) : see declaration of 'String::string'
String.cpp(29) : see declaration of 'String'
String.cpp(181) : error C2673: 'operator`*'' : global functions do not have 'this' pointers
0
 
efnCommented:
s * 3

is equivalent to

s.operator *(3)

So you want a function declaration like this:

String String::operator *(int mul)

This function is a member of the class, so you also have to declare the function in the class declaration.

And since the String class uses a fixed-size array, all operations that add to the string, like this one and operator +, must check that the operation does not overflow the bounds of the array, or you could have big trouble.
0
 
luna621Author Commented:
Only shows 'nono', and not 'nonono'...  Is my for loop wrong?


class String
{
    char string[80];

public:
    String( char *str = "" )
    {
        strcpy( string, str );
    }

    ...

    String operator *( int mul );

    void show_str()                   // display output to screen
    {
        cout << string;
    }
};

...


String String::operator *(int mul)
{
    String temp;
    int i;

    for(i = 0; i <= mul; i++)
    {
        strcpy( temp.string, string );
        strcat( temp.string, string );
    }
    return temp;
}


main()
{
    ...
    s = s * 3; // Now s contains "nonono".
    cout << "\n\n>>\t";
    s.show_str();
    ...
}
0
 
efnCommented:
Yes, your for loop is wrong.

Every time it calls strcpy, it copies string to temp.string, wiping out whatevermight have been built up there.  If you want to append string a number of times, you have to avoid calling strcpy, because it starts over with just one copy of string.
0
 
luna621Author Commented:
Ok, I tried this:

String String::operator *( int mul )
{
    String temp;
    int i;

    for( i = 0; i < mul; i++ )
    {
        //strcpy( temp.string, string );
        strcat( temp.string, string );
    }
    return temp;
}


... and it seems to work.  Is that okay, or should it be written otherwise?
0
 
luna621Author Commented:
I was also thinking of writing something somewhere along the lines of using the '/' operator to cut the string in half.  Is this allowed?
0
 
efnCommented:
> Is that okay, or should it be written otherwise?

Yes, that is okay, because the default constructor parameter of String initializes an object to contain an empty string.  So strcat works with it.

> I was also thinking of writing something somewhere along the lines of using the '/' operator to cut the string in half.  Is this allowed?

Sure.  It may not be generally useful in a string class, but I don't see any reason why you couldn't do it.  You'd have to make some arbitrary decision about which part of the string to return.
0
 
luna621Author Commented:
Okay.  I'll work on that.  I was working on another one while I was trying to figure out how to do the divide-string-in-half.  This one is supposed to reverse the string, but it gives me these errors.  Does that mean I can't use '~' to overload?  

Here are the errors:
--------------------------------------------------------------------------------------------------------------

String.cpp(44) : error C2808: unary 'operator ~' has too many formal parameters
String.cpp(181) : error C2664: 'String::mystrlen' : cannot convert parameter 1 from 'String' to 'char *'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
String.cpp(183) : error C2676: binary '[' : 'String' does not define this operator or a conversion to a type acceptable to the predefined operator




Here is the code:
--------------------------------------------------------------------------------------------------------------

String String::operator ~( String str )
{
    String temp;
    int i;

    for(i = mystrlen(str) - 1; i >= 0; i--)
    {
        temp = str[i];
        strcat( temp.string, string );
    }
    return temp;
}


int mystrlen( char *str )
{
    int i;

    for( i = 0; str[i]; i++ );  // find the end of the string
    return i;
}
0
 
luna621Author Commented:
Oh... is it because I don't have a mystrlen in the String class?
0
 
efnCommented:
> String.cpp(44) : error C2808: unary 'operator ~' has too many formal parameters

~ is a unary operator.

~s

is equivalent to

s.operator ~()

So it should not take a parameter.

> String.cpp(181) : error C2664: 'String::mystrlen' : cannot convert parameter 1 from 'String' to 'char *'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

You declared mystrlen to take a char* parameter, but passed it a String.  The compiler does not know how to convert a String to a pointer to char.

> String.cpp(183) : error C2676: binary '[' : 'String' does not define this operator or a conversion to a type acceptable to the predefined operator

You subscripted str, which is a String, but there is no subscripting operator for the string class.
0
 
luna621Author Commented:
Thank you for pointing those out.  I've been working on this all day and need sleep.  I'll be back tomorrow.  Thank you again!  You're a good guy :)
0
 
luna621Author Commented:
Error:

String.cpp(182) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'char' (or there is no acceptable conversion)


---------------------------------------------------------------------------------------
String String::operator ^( char* str )
{
    String temp;
    int i;

    for( i = mystrlen( str ) - 1; i >= 0; i-- )
    {
        temp = str[i];
        strcat( temp.string, string );
    }
    return temp;
}
0
 
luna621Author Commented:
Sorry, it was pointing at this line for the error:

...
temp = str[i];
...
0
 
luna621Author Commented:
Oh, str is now a char* and not a string.  Hmm... how do I get this to work?
0
 
efnCommented:
What are you trying to do?
0
 
luna621Author Commented:
I am trying to reverse a given string.
0
 
efnCommented:
^ is a binary operator.  With the declaration you have, you would be able to do something like this:

String s("abc");
char a[] = "def";
String q = s ^ a;

What's the given string you want to reverse, s or a?  Or what result do you want in q?  It looks like the code you have, if it worked, would generate "fabceabcdabc" in q.
0
 
luna621Author Commented:
Oh, I see what you mean.  I'll tinker around with that.  I'll post another question if I have any problems.  Thanks again efn!  Points time!! :)
0
 
efnCommented:
It has been my pleasure to assist you.
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 17
  • 9
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now