简体   繁体   中英

Returning a vector of unique_ptr from function

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_ptr or have to make a manual copy and std::move it. However, I take you only want to provide access to the Unit s (for whatever reason...), so simply return a reference:

std::vector<std::unique_ptr<Unit>> const& getUnits() const
{
  return mUnits;
}

(The const is only needed if you don't want to give write access into the vector.)

Now, a few questions arise still: Why is ~Tile virtual ? 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 Tile in 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 using shared_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?"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM