I am currently going through the book Head First Object Oriented Analysis and Design and also getting used to some of the features of C++11 (especially unique_ptr and move semantics) at the same time. In the book, they give the design of a strategy board game as an example. It has a board, tiles and units on tiles. The code is in Java and I was trying to rewrite it in C++. In Java, the tile class is as follows:
public class Tile
{
private List units;
public Tile()
{
units = new LinkedList();
}
protected void addUnit(Unit unit)
{
units.add(unit);
}
protected List getUnits()
{
return units;
}
}
I did the same thing in c++ first using shared_ptr. It worked but very slow compared to my second version which used raw pointers. I then tried unique_ptr:
class Tile
{
public:
Tile();
virtual ~Tile();
void addUnit()
{
mUnits.push_back(std::unique_ptr<Unit>(new Unit());
}
std::vector<std::unique_ptr<Unit>> getUnits()
{
return mUnits;
}
private:
std::vector<std::unique_ptr<Unit>> mUnits;
};
the compiler does not like the getUnits. From what I understand it comes from the fact that the copy constructor is disabled in the unique_ptr. How would you return the list of vectors?
Thanks!
A value returned in C++ incurs a copy – if that’s what you want, you can’t use
unique_ptror have to make a manual copy andstd::moveit. However, I take you only want to provide access to theUnits (for whatever reason…), so simply return a reference:(The
constis only needed if you don’t want to give write access into the vector.)Now, a few questions arise still: Why is
~Tilevirtual? I see no need.Why do you use an owning ptr to point to the units? In the original Java code, you get handed a reference to an external Unit and only store a reference – if the
Tilein the Java code is destroyed, the units are not (from what I can see), as long as they are referenced somewhere else. To achieve the exact same in C++, you were correct in usingshared_ptr.Of course, you could just clarify who is the real owner of the units and operate accordingly – if it is not
Tile, use a raw pointer. See also “Which kind of pointer do I use when?”