【问题标题】:How to pass abstract-typed array as function parameter?如何将抽象类型数组作为函数参数传递?
【发布时间】:2012-05-06 02:17:07
【问题描述】:

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

例如(“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’

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

【问题讨论】:

  • 顺便说一句,错误消息暗示您在 std 命名空间内定义了 Testable,这是不允许的...
  • 你应该给我们Testable的定义

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您不能拥有一个对象数组,然后将其转换为其他对象数组。 想想看,如果 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);
    }
    

    【讨论】:

    • 您的代码在testables[i]-&gt;afficher(); 行抛出此错误:base operand of ‘-&gt;’ has non-pointer type ‘std::Testable
    • @weberc2 它对我有用:codepad.org/pNWtj8yV 错误必须在其他地方。正如其他人指出的那样,不要在 std::. 中声明自己的类型。
    【解决方案3】:

    试试这个:

    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) {
    

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

    【讨论】:

    • 这是完全错误的。尝试使用 sizeof(Testable) 跨越 Vecteur 数组将在第一个之后给出错误的指针。 codepad.org/ysaJnd5T
    • 对。这就是尝试一次做 8 件事时会发生的情况;-) 感谢您提供指向键盘的链接(我使用过 Ideone - 并且应该在这篇文章中使用)。 +1。我将使用有效的东西进行编辑 - 模板类型。
    猜你喜欢
    • 2021-06-29
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2018-01-04
    • 1970-01-01
    相关资源
    最近更新 更多