修改
我想下面的代码假设我有一个addChild()的重载版本,它接受一个已经包装在unique_ptr中的Sprite,其中获取所有权就没问题了。我以为在别人做之前我会提到它。 :)。经过漫长的一天后,我在这里编写了所有代码,所以请把它作为伪代码质量,只是为了证明手头的问题。
原始问题
我正在编写一个框架,其中有一个显示列表,父母/孩子等等。我认为使用unique_ptr<Sprite>
就是这样的方式,因为当你将一个孩子添加到父母时显示对象,父母现在成为该子女的唯一所有者是合乎逻辑的。
但是,会有一些方法可用,例如getChildAt(index)
和getChildByName
等,我认为这些方法应该返回引用或指针值,因为这些方法只是为了将子项暴露给操作,不转让所有权。
最后,问题和这个问题的原因,是在以下情况。让我们假设我们有两个Sprite
对象,它们是显示列表根目录Stage
的子对象。假设我们有第三个孩子雪碧。
Stage newStage;
std::unique_ptr<Sprite> parentOne(new Sprite);
std::unique_ptr<Sprite> parentTwo(new Sprite);
newStage.addChild(parentOne); //Stage takes ownership of parentOne
newStage.addChild(parentTwo); //Stage takes ownership of parentTwo
std::unique_ptr<Sprite> someChild(new Sprite);
parentOne->addChild(someChild) //parentOne takes ownership of someChild.
现在,在其他地方可以说游戏的代码库或使用此框架的任何内容,someChild
都可以通过getChildAt(int index);
访问。
Sprite& child = parentOne->getChildAt(0);
以下情况完全合法。
parentTwo->addChild(child);
如果父项存在,addChild
方法处理将子项从其前一个父项中删除,以便新父项现在可以使该子项成为显示列表其部分的一部分。
我将每个精灵中的孩子(ren)作为参考或指针返回,因为我们不想交出所有权(在getChildAt()
等方法中),只是提供对孩子的访问权限。我们不希望将其作为unique_ptr
移交,并使其超出范围而死亡。
然而,正如我所说,将这个孩子(现在通过引用或指针访问)传递给另一个容器是完全合法和正常的(假设在拖放操作中,拖动一个项目)列表到另一个)。我们现在遇到的问题是,独特的所有权需要从一个父母转移到另一个父母,但我们只有一个参考或原始指针。
我想知道这个问题的理解是什么。如果我返回指针,是否可以在此阶段正确转移所有权?
void Sprite::addChild(Sprite* newChildToOwn)
{
/* by checking newChildToOwn->parent we can see that the child is already owned
by someone else. We need to not only remove the child from that parents' part of the
display list and add it here, but transfer exclusive object ownership of newChildToOwn
to this->.
*/
}
答案 0 :(得分:5)
release方法为您提供指向对象的指针,并从unique_ptr
中释放它http://en.cppreference.com/w/cpp/memory/unique_ptr/release
对于你的结构,你应该有一个名为releaseChild(index)的方法,它通过返回指针来处理你的所有权。
答案 1 :(得分:3)
要转移所有权,您需要有权访问unique_ptr
,因为原始指针不知道如何使用它。
让删除子方法返回unique_ptr
是否有效,以便在传输过程中对象保持活动状态,Sprite
将能够获得所有权?这将允许您在其他地方使用引用。