【问题标题】:Passing an array of Child objects to a function that accepts Parent*将一组 Child 对象传递给接受 Parent* 的函数
【发布时间】:2016-04-28 12:30:26
【问题描述】:

我正在开发一个功能有限的嵌入式平台,因此向量/STL 不可用。

这可能是一个微不足道的问题,但我在 C++ 方面没有太多经验(只有 C 和 C#,这可能使我对明显的 C++ 方法视而不见)。

考虑以下示例:

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;
}

如果提供了一个指向派生类数组的指针,那么在 Test() 中迭代 parents 显然是有问题的,因为 的内存占用在迭代期间假定父代

我看到的唯一解决方案是传递 Parent 类型的指针数组(Parent** 父母),但这似乎很麻烦。是否有一些我不知道的 C++ 机制,比如将数组作为引用传递或其他什么?

【问题讨论】:

  • Test成为模板函数?使用指针数组(不是我真的推荐它,除非你的类是多态的)。解决方案(这些或其他)很大程度上取决于用例。

标签: c++ c++11 embedded avr-gcc


【解决方案1】:

您可以使用这种方法:

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

然后像这样使用它:

int main() {

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

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

    return 0;
}

【讨论】:

  • 你不应该为函数指定模板类型。你应该让编译器为你推导出来。
  • @NathanOliver 你是对的。我已经更新了我的答案。
  • 正如我所指出的,标准模板库不可用。
  • @Rev1.0 这不使用标准模板库。这是制作你自己的模板函数。
  • @Rev1.0 这不是来自 STL,它只是使用属于 C++ 语言的模板。
【解决方案2】:

如果模板不是一个选项,并且Test 的用户不能依赖Child 并且甚至不知道它的大小,那么您可以使用指针数组:

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);
}

请注意,在这个简单的示例中,我们确实知道我们传递其指针的对象的大小,但一般来说,我们可能无法为 Test 的所有用户做出该假设.

【讨论】:

  • 这种方法是我最初的方法,引用我自己的话:“我看到的唯一解决方案是传递一个 Parent 类型的指针数组(Parent** parents),但这似乎很麻烦。”不过感谢您对此进行验证。
  • @Rev1.0 是的,我注意到了。这是为那些正在寻找解决方案而无法选择其他答案的人准备的。
  • 这是正确的解决方案。传递模板数组的解决方案不适用于混合了不同派生类的数组。如果你可以使用 STL,你会使用 unique_ptr 或 shared_ptr 的向量。
【解决方案3】:

如果你不能使用模板,你可以这样做:

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]));
}

【讨论】:

  • 有趣但有点混乱的方法。我希望 C++ 能让事情变得更干净;)我想与此相比,我更喜欢“指针数组”方法。感谢您的反馈。
  • @Rev1.0:嗯,“指针数组”方法效率较低,我想你不会想要这样,因为你显然是在一个超级受限的系统上,但它是当然可行。
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多