views:

168

answers:

2

I have a URL class that overloads the ==, <, >, and != operators for simple comparison. The URL class has a string data member and some functions to act on the string. The operators work fine when tested with the URL class.

I also have a Page class that has a URL data member. I am trying to overload the same operators in the Page class. Equality in the Page class is based on equality of their respective URLs, so I use the URL class boolean operators in comparing pages. This creates some compiler errors that I cannot figure out. Code for URL operators:

bool URL::operator ==(URL & u) const {
    //url is the string instance variable
    return url == u.GetURL();
}

Code for Page operators:

bool Page::operator ==(Page & p) const {
    //url is the URL instance variable of the Page class
    return url == p.GetURL();
}

This produces errors like so:

src/Page.cpp: In member function ‘bool Page::operator==(Page&) const’:
src/Page.cpp:21: error: no match for ‘operator==’ in ‘((const Page*)this)->Page::url == Page::GetURL()()’
inc/URL.h:118: note: candidates are: bool URL::operator==(URL&) const

I predict that it is something dumb that I am forgetting. Will you prove me right?

edit: Const correctness has bitten me in the bum. Thanks for the help.

+6  A: 

It should have been:

bool URL::operator ==(const URL & u) const {
    //url is the string instance variable
    return url == u.GetURL();
}

And analogously for the other operators.

If you still get compiler errors, perhaps you haven't made GetURL() const as well:

std:string URL::GetURL() const {
    // whatever...
}
Eduardo León
Wonderful, thank you. I had to make both the Page class GetURL() and URL class GetURL() const functions. Dang brain.
Jergason
+1  A: 

I would also like to point out that methods (ie the public interface) are there to protect external entities from changes in the implementation details. Also that a class is automatically a friend of itself (for the same reason) and thus just accessing the members of the other object is OK.

bool URL::operator ==(URL & u) const {
    //url is the string instance variable
    return url == u.GetURL();
}

Can be written like:

bool URL::operator ==(URL & rhs) const
{
    return url == rhs.url;  // No need to use GetURL()
}

In my mind this makes the code clearer (but this again is an opinion your tastes may vary)

Martin York
Agreed. `GetURL()` is meant to be used outside the class.
Eduardo León
Thanks, that does make it cleaner.
Jergason
I've always gone the other way: `return GetURL() == rhs.GetURL();`. Function reuse.
GMan
@GMan: We are just checking state. If GetURL() has a side affect is that appropriate for testing state? But this is implementer call it all depends on the situation.
Martin York