以旧方式C++遍历对象指针数组(没有基于范围的 for)

Iterating through array of object pointers in C++ the old way (without range-based for)?

本文关键字:于范围 范围 for 遍历 C++ 对象 指针 数组 方式      更新时间:2023-10-16

我并不精通C++,但我得出了以下代码:

BaseManager* allManagers[] =
{
    mColorManager,
    mToolManager,
    mLayerManager,
    mPlaybackManager,
    mViewManager
};
for ( BaseManager* pManager : allManagers )
{
    pManager->setEditor( this );
    pManager->init();
}

我使用较旧的g++,所以我不能使用-std=c++11,我必须使用-std=c++0x。错误地查看"老式"等效项:":"标记之前的预期初始值设定项,我希望以下内容能够起作用:

for ( auto it = allManagers.begin(); it != allManagers.end(); ++it )
{
    BaseManager* pManager = *it;
    pManager->setEditor( this );
    pManager->init();
}

。但它失败了:

error: request for member ‘begin’ in ‘allManagers’, which is of non-class type ‘BaseManager* [5]’
error: unable to deduce ‘auto’ from ‘<expression error>’

所以我收集了,因为这个allManagers显然只是一个 C 数组,它不是一个带有方法的对象(如 .begin ) - 所以最后,我终于得到了那段编译:

for ( int i=0 ; i<5 ; i++ )
{
    BaseManager* pManager = allManagers[i];
    pManager->setEditor( this );
    pManager->init();
}

。但是,这需要我手动写入数组长度,这是我不喜欢的。

所以,我的问题是:在不使用基于范围的 for 循环的情况下遍历这样一个指针数组的正确方法是什么 - 而且,也不必显式输入硬编码数组长度?

您可以使用:

for ( auto it = std::begin(allManagers); it != std::end(allManagers); ++it )
{

但是,这些也是 C++11 功能。某些 C++11 之前的编译器可能支持它们,但不能保证。

如果没有 C++11 编译器,您可以使用:

size_t numObjects = sizeof(allManagers)/sizeof(allManagers[0]);
for ( size_t i = 0; i < numObjects; ++i  )
{
   BaseManager* manager = allManagers[i];

要么跟踪变量中的数组长度,要么使用 std::array 或 std::vector。

编辑:如果你想创建自己的ArrayLen()方法,你可以这样做:

template<class T, size_t Size>
static inline size_t ArrayLen(const T(&arr)[Size])
{
    return Size;
}

然后你可以这样做:

for(size_t i = 0; i < ArrayLen(allManagers); ++i)
{
    BaseManager * pManager = allManagers[i];

allManagers不是容器。它是一个指针数组,因此您不能使用 .begin() .

如果要确定数组的大小,只需执行以下操作:

int n = sizeof(allManagers)/sizeof(allManagers[0]);

查看此问题以获取更多信息。请注意,您的数组位于堆栈中。