如何将抽象类型数组作为函数参数传递?

时间:2012-04-25 11:47:14

标签: c++ inheritance polymorphism abstract-class parameter-passing

我想定义一个抽象基类,然后传递一个该类型的数组(显然是一个派生类的实例)作为函数参数,但是编译器对我大吼大叫。有什么想法吗?

例如(“Testable”是抽象的,“Vecteur”是具体的):

void Testeur::commencerTest(Testable testables[], int nTestables, string titre) {
    cout << "\n" << titre << "\n";
    for (int i=0; i < nTestables; i++) {
        testables[i].afficher();
    }
}

// in main function:
Vecteur v1 = Vecteur(1,2,3);
Vecteur v2 = Vecteur(4,5,6);
Vecteur vecteurs[] = { v1, v2 };
int nVecteurs = 2;

this->commencerTest(vecteurs, nVecteurs, "Some text");

编译器在上面代码的第一行说invalid abstract type ‘std::Testable’ for ‘testables’

如何将抽象类型的数组作为函数参数传递?

3 个答案:

答案 0 :(得分:5)

简短的回答是:你做不到。数组在C ++中不是多态的;这是有充分理由的 - 参见例如What is object slicing?。请记住这样做,例如arr[i],编译器需要知道每个元素有多大(计算地址偏移量);一般来说,这种计算对于派生类型来说是错误的。

您考虑使用函数模板,或者可能是(智能)指针的数组/容器。

答案 1 :(得分:1)

您不能拥有一个对象数组,然后将其强制转换为其他对象的数组。 想想看,如果Vecteur sizeof为16且Testable sizeof为4,那么这怎么可能起作用呢?

你想要的是一个指向对象的指针数组。

void commencerTest(Testable* testables[], int nTestables)
{
    for (int i=0; i < nTestables; i++)
        testables[i]->afficher();
}

int main()
{
    Testable* vect[10];

    for(int i=0; i<10; i++)
        vect[i] = new Vecteur();

    commencerTest(vect, 10);
}

答案 2 :(得分:0)

试试这个:

template <typename Type>
  void Testeur::commencerTest(Type *testables, int nTestables, string titre) {

代码最终会抱怨不知道数组的大小。多态性将通过指针而不是其他人已经注意到的数组来工作。

作为另一种可能性,您可以对静态数组的类型和数字使用编译时多态:

template<typename Type, size_t Num>
  void Testeur::commencerTest(Type (&testables)[Num], string titre) {

此外,标准库容器是一个很好的解决方案。