Hello again! In this video, we are going to look at using custom types with associative containers. By
a "custom type", I mean something that is not a built-in type or a C++ library class.
So this could be a class that you wrote yourself, or maybe some classes from a third party library.
We can use these custom types with all the C++ associative containers. So that is map, set, multiset
and multimap.
Either the ordered or the unordered versions. And we can use a custom type, either as the value of an associative
container, or as the key, or both.
As an example, we are going to represent a library of books. Some of you may have actually seen a
physical library of books(!)
If you have not, ask your parents, or maybe your grandparents :) We want to be able to search our library
to find a book, or maybe some books, written by a particular author. So it will need to have keys
and values.
We could have more than one book by the same author in our library.
So we need duplicate keys. And we would like the books to be in order.
So the obvious container is a multimap.
The key is going to be a string, which will be the name of the author. And the value will be an object
of a class, which has details about the book.
So we could write a class which looks like this.
So we call it book, which is very imaginative!
Sometimes it is good to have simple names, which are descriptive.
And then the fields for this, and then the members of this are the title and publisher, which are both
strings, and we have a constructor to initialize those members.
And then to represent the library, we have a multimap. This will have a string as the key, which
will be the author's name, and the value will be one of these book objects.
So here is some code with our book class. The title and publisher members. The constructor. I have added
a friend function which will print out the members of the class.
It needs to be a friend, so it can access the private members.
Then we have our multimap, which will represent the books in the library.
The key is the author's name, a string. And the value is the book class with the details of the book.
And then to add some books to the library, we create a book object.
So we give the title and the publisher as arguments to the constructor. And then we call insert(),
and we provide a pair, with the author's name and the book object.
And I think you may have heard of this author before!
And, by the way, it is well worth adding some or all of these books to your C++ library,
if you want to have one. They all address different requirements, really. "Programming Principles and
Practice" is for people who are starting out in programming.
And it teaches you how to program, using the C++ language. So it might be a bit basic for people who
are doing this course.
"C++ Primer" is a fairly readable reference book, on C++11.
"The C++ Programming Language" is a very technical reference book, and "A" Tour of C++" is a quick guide
for people who already have a good knowledge of other programming languages, and want to learn all the
important features about C++.
So let's see what we get when we print these books out.
So we get the author and the book details. These are ordered by the author.
They are in alphabetical order, because they are using the string's less-than operator to order them.
However, if we look at the details of the books, we see that they are not
in order. So Bjarne Stroustrup has "Programming Principles" first and then "A Tour of C++" at the end.
If we had a real library, then the books would usually be arranged by title for an author. So it would
be nice to have all the books for one author grouped together and arranged by their title.
So the multimap will sort the books in order of their key, which is the author. Books by the same author
will be grouped together, but the titles will probably not be in order.
And we would like to be able to do that.
If we were doing database programming, we would need to provide something called a "compound key".
So that would force the sort process to look at both the author and the title. With C++ associative
containers,
we can do that by writing a class which represents this key.
So we need to have a class which has the author and the title.
And it will make the sort look at the author first and then the title.
So our class would look like this.
I am going to call it book_idx, because it is like an index for the book.
We are going to have the author and the title as fields, and maybe some public functions if we need them.
And then our multimap will have an object of this class as the key, and then the book object as the value.
For ordered associative containers, I hope you remember, the less-than operator is the one which sorts the
keys.
In fact, if you try to create a container and the key does not support the less-than operator, then
that is not going to compile.
We need to provide a less-than operator for our class, and we want to make sure that it is going to
sort the elements in the way we want.
So we need to sort the authors first and then, if the authors are the same, we need to sort the titles.
So the title is going to act as a kind of tie-break if the authors are equal. For an unordered container, it is
a bit more complicated.
We need to tell the container how to hash the keys.
There is a library hash function, which is templated.
It has specializations for all the types in the library and the built-in types.
But if we are using our own class, we need to provide our own specialization.
So we need to write a hash function.
And also, we need to define the equality operator.
So this is a bit more complicated.
So we are going to stick to ordered containers, for this example.
Before we get on to actually implementing the less-than operator for our class, it might be worth having
a quick digression on what it means for things to be equal. In C++,
there is three possibilities.
You can have two objects, which are the same objects in memory. So they occupy the same address,
but they are referred to differently.
So for example, if we have a book, I could say that, "this is my book" and you could refer to it as "James's
book".
But they are still both
the same book. It is still the same copy of the book.
We could have two objects which have different memory addresses, but all their values are the same, all their
members. And that corresponds to having two different copies of the same book.
And then finally, we can have two objects which have some values which are different.
But the values which we are concerned about are the same, and they only differ in things which are
not relevant to us.
So, for example, we could have two copies of a book.
One is hardback, one is paperback.
But if we are only interested in the actual content, then those are
actually, the same thing, as far as we are concerned. And usually in C++, when we say that two objects
are equal,
this is what we are alluding to.
So here is how we would write our less-than operator.
I hope this is vaguely familiar!
It takes an object of the same type by reference to const.
If the authors are the same, we want these to be ordered by title. So if the authors are equal, then
we compare the titles, and we can just call the string's less-than operator, because these are strings.
If we get here, then the authors are different, so we just compare them by the author.
So this is the class for the book index. The author and title members. The constructor. Then the less-than
operator, which we just saw on the slide. And then a function for printing them out again.
And then similar, but not quite the same. Because we have moved the title out of the book field, I have
added some more details.
So now we have the publisher, the edition and the date.
And then we create our multimap object, with the book index as the key, and a book object as the value.
Then we create a book object, so published by Addison Wesley,
2nd Edition, 2014. Then we create an index object.
So the author and the title. And then we add these as, a pair, to the multimap.
And now we get the title and the author, and then the book details. We have the authors in alphabetical
order.
And then we have the books for Bjarne Stroustrup, which are also grouped in alphabetical order.
OK, so there we are.
So that is it for this video.
I will see you next time.
Until then, keep coding!