我目前正在阅读Head First面向对象分析和设计这本书,同时也习惯了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中禁用了复制构造函数的事实。你会如何返回向量列表? 谢谢!
答案 0 :(得分:15)
C ++中返回的值会产生一个副本 - 如果这是您想要的,则不能使用unique_ptr
或必须手动复制并std::move
。但是,我带你只想提供Unit
的访问权(无论出于何种原因......),所以只需返回一个引用:
std::vector<std::unique_ptr<Unit>> const& getUnits() const
{
return mUnits;
}
(只有在您不希望向矢量提供写入权限时才需要const
。)
现在,仍然会出现一些问题:为什么~Tile
virtual
?我认为没有必要。
为什么使用拥有 ptr指向单位?在原始Java代码中,您将获得对外部单元的引用并仅存储引用 - 如果Java代码中的Tile
被销毁,则单元不是(从我可以看到的),只要它们被引用到其他地方。要在C ++中实现完全相同,使用shared_ptr
时是正确的。
当然,您可以澄清谁是单位的真正所有者并进行相应操作 - 如果不是 Tile
,请使用原始指针。另请参阅"Which kind of pointer do I use when?"