简体   繁体   中英

Passing an array of Child objects to a function that accepts Parent*

I am working on an embedded platform with limited capabilities, so vectors/STL are not available.

This may be a trivial problem, but I do not have much experience in C++ (only C and C#, which may make me blind to an obvious c++ way to do it).

Consider the following example:

class Parent {
};

class Child : public Parent {
};

void Test(Parent* parents, uint8_t parentCount) {
    // Accessing parent[x] is problematic when 'parents' contains a derived type
}

int main() {
    // This is OK
    Parent parents[3];
    Test(parents, 3);

    // This causes problems
    Child children[3];
    Test(children, 3);

    return 0;
}

Obviously it is problematic to iterate over parents in Test() , if a pointer to an array of derived classes is provided, because the memory footprint of Parent is assumed during the iteration.

The only solution I see is to pass an array of pointers of type Parent (Parent** parents), but that seems cumbersome. Is there some C++ mechanism I am not aware of, like passing the array as a reference or something?

You could use this approach:

template <class T>
void Test(T* parents, uint8_t parentCount) {
    // Code that accesses parent[x]
}

and then use it like this:

int main() {

    Parent parents[3];
    Test(parents, 3);

    Child children[3];
    Test(children, 3);

    return 0;
}

If template is not an option and when the user of Test can not depend on Child and can't even know it's size, then you can use an array of pointers:

void Test(Parent** parents, uint8_t parentCount);

int main() {
    Child children[n];
    Child* pointers[n];
    for(int i = 0; i < n; i++)
        pointers[i] = &children[i];
    Test(pointers);
}

Note that in this trivial example, we do know the size of the object whose pointers we pass, but in general, we may not be able to make that assumption for all users of Test .

If you can't use templates, you can do this:

class Parent {
};

class Child : public Parent {
};

void Test(Parent* parents, uint8_t parentCount, uint16_t parentSize) {
    for (uint8_t ii = 0; ii < parentCount; ++ii) {
        void* parentvoid = reinterpret_cast<char*>(parents) + ii * parentSize;
        Parent* parent = parentvoid;
    }
}

int main() {
    Parent parents[3];
    Test(parents, 3, sizeof(parents[0]));

    Child children[3];
    Test(children, 3, sizeof(children[0]));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM