• ベストアンサー

c++のvirtual関数および継承について

以下のプログラムで間違っている部分が分かる方、ご指摘お願い致します。 私の稚拙な腕では、どこが間違っているのかさっぱり分かりません。 以下のプログラムは、クラスticketを継承して、airplaneTicket、cinemaTicketを作成し、チケットの情報を入力し、最後に出力するものです。コンパイルエラーの箇所はコメントアウトしておきました。メイン関数の中に計5箇所あります。 よろしくお願い致します。 #include<string> #include<iostream> #include<vector> using namespace std; class ticket{ public: string ID; string seat; int price; ticket(){ cout << "ticket default constructor" << endl; ID="not Known"; seat="not Known"; } ticket(string i, string t){ cout << "ticket parameter-constructor" << endl; ID=i; seat=t; } virtual void setPrice(int p)=0; void printInfo(){ cout << ID << " " << seat << endl; } }; class airplaneTicket: public ticket{ public: string flight; airplaneTicket(){ cout << "airplane default constructor" << endl; flight="not known yet"; } airplaneTicket(string i, string t, string f):ticket(i, t){ cout << "airplane parameter-constructor" << endl; flight=f; } virtual void setPrice(int p){ string type; cout << "enter class type: "; cin >> type; if(type=="business") price=p*2; else price=p; } void priceInfo(){ cout << ID << " " << seat << " " << price << " " << flight << endl; } }; class cinemaTicket: public ticket{ public: cinemaTicket(){ cout << "cinema default constructor" << endl; } cinemaTicket(string i, string t):ticket(i, t){ cout << "cinema parameter-constructor" << endl; } }; int main(){ ticket tList[100]; //error: invalid abstract type 'ticket' for 'tList' tList[0]=new airplaneTicket("239", "d34", "f345"); //error: no match for 'operator=' in 'tList[0] tList[1]=new airplaneTicket(); // error: no match for 'operator=' in 'tList[1] tList[2]=new cinemaTicket("245", "a23"); //error: cannot allocate an object of abstract type 'cinemaTicket' tList[3]=new cinemaTicket(); // error: cannot allocate an object of abstract type 'cinemaTicket for(int i=0;i<4; i++){ tList[i].printInfo(); } return 1; }

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

もしかしたら、以前にJavaをやっていませんでしたか?なんとなく、Javaの様な書き方なので。 メッセージからするとg++のようですので。 >ticket tList[100]; //error: invalid abstract type 'ticket' for 'tList' ちゃんと理由が書いてあります。メッセージはこう続きます。 note: because the following virtual functions are pure within ‘ticket’: note: virtual void ticket::setPrice(int) ticket tList[100]は、ticketのインスタンスを100個作ろうとしてます(Javaと違って) が、 純粋仮想関数ticket::setPriceがあるのでインスタンスは作成できずエラーになります。 後ろでnewでairplaneTicket、cinemaTicketを作って代入しているので、ここはticketへのポインタ ticket * でしょう >tList[2]=new cinemaTicket("245", "a23"); //error: cannot allocate an object of abstract type 'cinemaTicket' ここも同様、継承したcinemaTicket::setPriceが純粋仮想関数のままです。 >tList[0]=new airplaneTicket("239", "d34", "f345"); //error: no match for 'operator=' in 'tList[0] new ariplaneTicketは「ariplaneTicketへのポインタ_を返します。 「ticketのインスタンス」 = 「ariplaneTicketへのポインタ」 という=演算子が定義されていないためのエラーです。 tListの宣言をポインタに変えることでエラーは出なくなります。 > tList[i].printInfo(); ポインタへ宣言を変えたので、 tList[i]->printInfo(); > return 1; 終了コードは「正常終了は0,異常終了は0以外」というのが普通です。 今回はこれで終了なのでよいのですが、本来はnewで確保したらdeleteで解放しないとメモリーリークを起こします。 以上を踏まえ、main関数だけ書くと int main(){ ticket* tList[100]; tList[0]=new airplaneTicket("239", "d34", "f345"); tList[1]=new airplaneTicket(); tList[2]=new cinemaTicket("245", "a23"); tList[3]=new cinemaTicket(); for(int i=0;i<4; i++){ tList[i]->printInfo(); } // メモリの解放 for(int i=0;i<4; i++){ delete tList[i] ; } return 0; }

liuziq
質問者

お礼

ご回答ありがとうございました。 ご指摘の通りJavaをやってました。しかし、それが裏目に出てabstructと同様に考えて処理しようとして失敗してしまったようです。また、純粋仮想関数は継承する全てのクラスで定義しなければならないことが分からなかったという勉強不足も失敗要因でした。 質問にコンパイラ名を書くべきでした。このような稚拙な質問に懇切丁寧にご回答下さってありがとうございました。もしまた質問するときがあるとしたら、もっと勉強して上で、分かりやすい質問を書くように心掛けます。 お陰様でうまくいきました。この度は本当にありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.1

1. cinemaTicket::setPriceが定義されていない。 2. ticket tList[100]; は ticket* tList[100]; の誤り。 3. tList[i].printInfo(); は tList[i]->printInfo(); の誤り。

liuziq
質問者

お礼

ご回答ありがとうございます。 非常に単純明快なご指摘で、見た瞬間に自分の間違いがよく分かりました。 お陰様でうまくできました。 この度は、迅速に対応して頂きありがとうございました。

すると、全ての回答が全文表示されます。

関連するQ&A