user2479147
user2479147

Reputation: 1

overloading operator< for pointers to class object

I'm trying to figure out how to implement an operator< overload for an Item Pointer class that points to an Item class object. It is part of a program that stores pointers to Items in an STL set. The overload is necessary for an ordered STL set (alphabetical by title). I know the code is wrong for the ItemPtr overload below. I thought I could dereference the pointer to get at the actual item, but I don't know how to implement this. I hope I'm on the right track. I appreciate any pointers (no pun intended) anyone can share.

bool operator<(const Item& i1, const Item& i2)
{
    const char* str1 = i1.getTitle().c_str();
    const char* str2 = i2.getTitle().c_str();
    return strcmp(str1, str2);
}

bool operator<(const ItemPtr& ip1, const ItemPtr& ip2)
{
    const Item& i1 = *ip1;
    const Item& i2 = *ip2;
    return i1 < i2;
}

Thanks.

Upvotes: 0

Views: 132

Answers (2)

Gonmator
Gonmator

Reputation: 780

The wrong thing in your implementation is not comparing ItemPtrs, but comparing Items: strcmp() will return a not zero value when str1 and str2 are different, and returning non-zero value means true. You cannot get ordered elements if a < b and b < a at the same time. Because ItemPtr comparison is implemented as function of Item comparison, it will have the same problem.

The solution given by John Dibling is easy and right if you're sure ItemPtr always contains a valid Item reference:

bool operator<(const ItemPtr& ip1, const ItemPtr& ip2)
{
    return ip1->getTitle() < ip2->getTitle();
}

If you need to compare Items anyway:

bool operator<(const Item& i1, const Item& i2)
{
    return i1.getTitle() < i2.getTitle();
}
bool operator<(const ItemPtr& ip1, const ItemPtr& ip2)
{
    return *i1 < *i2;
}

If you cannot assume ItemPtr store a valid reference, you will have to check that case. (But probably you can assume that).

Upvotes: 0

John Dibling
John Dibling

Reputation: 101456

The simplest method, assuming you guarantee there are no invalid pointers in the set and getTitle() is const:

bool operator<(const ItemPtr& ip1, const ItemPtr& ip2)
{
  return ip1->getTitle() < ip2->getTitle();
}

I would caution however that needing to do this kind of thing triggers my sense that there is something possibly wrong with your design. In particular, why are you storing pointers-to-Item in your set, rather than just the Item itself? Is this really needed?

Upvotes: 2

Related Questions