我正在尝试将一些代码从Objective-C转换为C++
我有一个CCNode,我想递归遍历它拥有的所有节点。
我不知道怎么写这个:
for(CCNode* child in [self children])
{
}
谁能为我翻译这个?
更新:这是来自另一个SO答案的代码:CCNode递归getChildByTag
由于C++中没有快速枚举,因此可以通过迭代器或计数器对其进行迭代,并在计数器达到集合大小时停止。然后使用 objectAtIndex(( 获取每个对象:
for(int i = 0; i < getChildren()->count(); i++)
{
CCNode *child = getChildren()->objectAtIndex(i);
< Your code >
}
在 C++11 中,我们有基于范围的 for
循环,它们具有类似的语法。
为此,您需要一个基于迭代器的包装器。
最简单的方法是使用 # include <boost/iterator/iterator_facade.hpp>
. 将基于索引的容器包装在 begin
/end
的iterator_facade
中非常容易。
如果您编写了struct my_iterator:boost::iterator_facade<my_iterator> {...};
类型,则只需编写my_iterator begin( CCArray& )
、const
版本和end
版本。
完成此操作后,您将获得:
for( CCObject* obj : *getChildren(( (这很接近,但使用 CCObject
而不是 CCNode
. 你碰巧知道this
的孩子是CCNode
,但 Cocos2d 接口只告诉你孩子是CCObject
。
我会编写一个 CCArrayAs<T>
适配器函数,该函数返回带有信息类型的包装CCArray
T
。 即:
template<typename T>
struct CCArrayAs {
CCArray* arr;
};
您会注意到,在任何地方都没有使用类型T
。 我们再次编写迭代器,但对于上述struct
,返回类型而不是CCObject*
是使用 static_cast
的T*
。 然后我们编写begin( CCArrayAs& )
、end
和const
版本,我们从中得到的是:
for( CCNode* node : CCArrayAs<CCNode>(getChildren()) )
这与Objective-C语法非常接近。 如果你想要一个更漂亮的语法,写CCArrayAs<CCNode> GetChildren( CCNode* self ) { return self->getChildren(); }
,给你:
for( CCNode* node : GetChildren(this) )
这样做的缺点是它有很多样板文件,所有这些都是为了获得稍微漂亮的语法。 这是你希望 Cocos2d 开发人员能做的事情,而不是自己做。
如果您不想完成所有这些工作,只需循环访问索引即可。 请参阅@RamyAlZuhouri对该解决方案的回答。 这要容易得多。
我假设你使用的是Cocos2d-iPhone的c ++端口?如果是这种情况,那么您可以使用 Cocos2d-x 的宏来迭代 CCArrays。
例:
CCObject* pObj = nullptr;
CCARRAY_FOREACH(getChildren(), pObj)
{
// do something
}