The Big Three of C++ Classes

I ran into an interesting problem while working on some code, and I thought it would probably be a good idea to, well, document the problem so I can remember it in the future.

The problem was this: I have a C++ class which is the key index in a std::map class. This C++ class wraps a Mac CFUUID object and provides a unique index based on UUID. And it was mysteriously crashing.

The root of the problems I had with my class were this:

(1) I wasn’t declaring the big three entry points for a C++ class to be used as an object within a C++ container class, like a std::map class. For the handful of people out there who don’t know, these entry points are the copy constructor, the copy operator, and the destructor. In my case, I was missing the following:

class CStdUuid {
    public:
        CStdUuid(const CStdUuid &);
        ~CStdUuid();
        CStdUuid &operator = (const CStdUuid &);

(2) In order to be used properly for comparing keys within a map, I also needed to properly declare the following compare operators:

        bool operator == (const CStdUuid &) const;
        bool operator < (const CStdUuid &) const;

Now I’m not quite sure off the top of my head if I only need to declare these two operators to be used as a key in a std::map class, or if this just happens to be true for my particular implementation of the standard C++ template library. I’m sure a quick search with Google will yield an answer.

But why my particular implementation was crashing was simple: my implementation of the CStdUuid::operator < operator was screwed up. Because my class was returning true if the items were equal, and not when my class was less than the provided class, the std::map class became confused, and was crashing mysteriously.

Which is today’s lesson of the day: if std::map is crashing mysteriously, check your compare operators, since the tree structure inside std::map may be getting munged by an incorrectly declared compare operation.

Leave a comment