0

私は抽象基本クラスを定義し、その型の配列(明らかに派生クラスのインスタンスでいっぱい)を関数のパラメータとして渡したいのですが、コンパイラは私に怒鳴ります。何か案は?例えば抽象型配列を関数パラメータとして渡すにはどうすればよいですか?

(「テスト可能」は「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’言います。

どのように抽象型の配列を関数のパラメータとして渡すことができますか?

+4

エラーメッセージは、あなたが 'std'名前空間の中で' Testable'を定義したことを意味しています... –

+0

Testable –

答えて

5

短い答えは:できません。配列はC++では多態的ではありません。これは正当な理由によるものです。 What is object slicing?。たとえば、 arr[i]、コンパイラは各要素の大きさを知る必要があります(アドレスオフセットを計算するため)。この計算は一般に、派生型については間違っています。

関数テンプレート、または(スマート)ポインタの配列/コンテナを使用することを検討してください。

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

あなたのコードはこのエラーをスローします: ' - > 'の基本オペランドは' testables [i] - > afficher(); '行で非ポインタ型' std :: Testable'を持ちます。 – weberc2

+0

@ weberc2それは私のために働く:http://codepad.org/pNWtj8yV エラーは別の場所にある必要があります。他の人が指摘しているように、std ::の中に独自の型を宣言しないでください。 –

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

はまた、標準ライブラリコンテナは良い解決策です。

+1

これは完全に間違っています。 sizeof(Testable)でVecteurの配列を跨ぐことは最初のものの後に間違ったポインタを与えるでしょう。 http://codepad.org/ysaJnd5T –

+0

右。これは一度に8つのことをしようとしたときに起こることです;-)コードパッドへのリンクをありがとう(私はIdeoneを使用しました - そして、この投稿を持っているべきです)。 +1。私は動作するもので編集します - テンプレートをタイプしてください。 – emsr

関連する問題