我想定义一个抽象基类,然后传递一个该类型的数组(显然是一个派生类的实例)作为函数参数,但是编译器对我大吼大叫。有什么想法吗?
例如(“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’
。
如何将抽象类型的数组作为函数参数传递?
答案 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) {
此外,标准库容器是一个很好的解决方案。