Go back to Richel Bilderbeek's homepage.
Go back to Richel Bilderbeek's C++ page.
This is part #0 of the answer of exercise #3: Don't give away your internals.
Let's start by defining a test suite. Note that the definitions are not needed, the compiler will give the warnings and errors needed already.
#include <vector> |
For the GetAnimals member function, there are many possibilities:
These sixteen possible member functions are:
std::vector<Animal> GetAnimals() ; |
The first halve to be taken off the list of possiblities are those that return a copy of the std::vector of Animals. We don't need a copy of all those animals (imagine that a Zoo has millions of animals!). We do need to do is get a safe read-only reference to the animals (Note: perhaps later we will get back to this!).
The second halve to be taken off the list of possiblities are the non-const-methods. We intend to only read from the Animals, so it should not change our Zoo. It should also be possible to read the Animals from a const Zoo.
This leaves only four options left, which I'll give numbers from now on:
std::vector< Animal>& GetAnimals0() const; |
Now the real tests start, even before defining the GetAnimal member functions.
The following line must not compile:
zoo.GetAnimalsX()[0].mX = 123; |
Three out of four correctly refrain from compiling, where GetAnimals0 just performs the unwanted modification. GetAnimals0 is marked as a potential source for bugs, and taken off our list.
With three member functions left in the race, it's time to define them:
const std::vector< Animal>& GetAnimals1() const { return mAnimals; } |
It appears that GetAnimals2 and GetAnimals3 do not compile. This is correct: we indeed give away a reference to a std::vector<Animal> instead of to a std::vector<const Animal>. If we want to return a std::vector<const Animal> then we need to make a copy of all those animals. Let's refrain from this (for now) and call GetAnimals1 the winner.
struct Zoo |
Go to the answer of the follow-up question: Answer of exercise #3: Don't give away your internals, #1
The exercise is called 'Don't give away your internals' (after [1]). One of the points of this item was the question: 'What do you want to do with this information?'. If you want to use std::cout on the implementation of Zoo (that is, the std::vector of Animal), why not enable to use std::cout on Zoo itself? Think if you perhaps do not need the GetAnimals (or similar, as in your code) method after all.
Go back to Richel Bilderbeek's C++ page.
Go back to Richel Bilderbeek's homepage.