20

我目前正在阅读《Head First Object Oriented Analysis and Design》一书,同时也习惯了 C++11 的一些特性(尤其是 unique_ptr 和移动语义)。在书中,他们以策略棋盘游戏的设计为例。它有一个板,瓷砖和瓷砖上的单位。代码是用 Java 编写的,我试图用 C++ 重写它。在 Java 中,tile 类如下:

public class Tile
{
    private List units;

    public Tile()
    {
        units = new LinkedList();
    }

    protected void addUnit(Unit unit)
    {
        units.add(unit);
    }

    protected List getUnits()
    {
        return units;
    }
}

我首先使用 shared_ptr 在 c++ 中做了同样的事情。与我使用原始指针的第二个版本相比,它工作但非常慢。然后我尝试了 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;

};

编译器不喜欢 getUnits。据我了解,它来自于复制构造函数在 unique_ptr 中被禁用的事实。你将如何返回向量列表?谢谢!

4

1 回答 1

20

C++ 中返回的值会产生一个副本——如果这是你想要的,你不能使用unique_ptr或必须手动复制std::move它。但是,我认为您只想提供对Units 的访问(无论出于何种原因......),所以只需返回一个引用:

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

const仅当您不想授予对向量的写访问权限时才需要。)

现在,仍然存在一些问题:为什么~Tile virtual?我看没必要。

为什么你使用拥有的ptr 来指向单位?在原始 Java 代码中,您获得了对外部单元的引用,并且只存储了一个引用 - 如果TileJava 代码中的. 为了在 C++ 中实现完全相同,您正确使用shared_ptr.

当然,您可以明确是单位的真正所有者并进行相应操作 - 如果不是 Tile,请使用原始指针。另请参阅“我何时使用哪种指针?”

于 2012-09-06T14:53:25.873 回答