• ベストアンサー

オーバーロード関数について質問があります。

今、病院の入院/外来患者のの状況と請求金額の計算のためのプログラムを作成しています (まだ完全なプログラムではありません)。 4つの引数(days, rate, medi, service)を持つ関数と2つの引数(medi, service)を持つ関数(関数名は同じ)を別々に計算させたいのですが、main()から呼ぶときにそれぞれ4つと2つの引数を指定しないと「0個の引数を持つオーバーロードされた関数はありません」と怒られてしまいますよね? しかし、どう指定してよいのか分かりません。 classはpatient.hの中で定義しているのでmainからは見えませんよね? なので"double charge_calc(medi, charge);"などとやってもシンタックスエラーになってしまいます。 どのように指定すればよいのか教えてください。 尚、OKWebの文字の制限がありますので今回は抜粋して載せますが、後で補足することもできます。 少し急いでいます。 どうかよろしくお願いします。 === main.cpp === total = inp.charge_calc(); cout << "Total: " << total << endl; total = outp.charge_calc(medi, service); cout << "Total: " << total << endl; === patient.cpp === double patient::charge_calc(short days, double rate, double medi, double service) { return (days * rate) + medi + service; } double patient::charge_calc(double medi, double service) { return medi + service; } === patient.h === class patient { public: patient(); virtual ~patient(); void ienter_information(); void oenter_information(); double charge_calc(short, double, double, double); double charge_calc(double, double); private: char condition; string fName; string lName; char sex; short days; double rate; double medi; double service; };

  • libre
  • お礼率93% (230/245)

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

  • ベストアンサー
noname#30727
noname#30727
回答No.2

設計に問題があるような気がします。 ienter_information() で入力した値は、patient のメンバに保存されるので、charge_calc が引数を必要とする理由がありません。 例えば、 total = inp.charge_calc_type1(); total = outp.charge_calc_type2(); というような、違う計算をする関数を2つ作ればいいのではないでしょうか。 今の構造のままでなんとかしなければならないのなら、days、rate、medi、service を public にして、 total = inp.charge_calc(inp.days, inp.rate, inp.medi, inp.service); total = outp.charge_calc(outp.medi, outp.service); こんな感じに、つじつまあわせをするしかないです。

libre
質問者

お礼

そのつじつまあわせの案を採用しました。 実は total = inp.charge_calc(inp.days, inp.rate, inp.medi, inp.service); は質問をする前に最初に試した方法でした。 privateから外してpublicにしてしまえばよかったのですね。 また、お世話になるかもしれません。 ありがとうございました!

libre
質問者

補足

只今、修正中です。しばらくお待ちください。 m(__)m

その他の回答 (2)

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.3

既に#2の方が回答されていますが、ienter_information()で入力した値を利用するならば、charge_calc()の引数は必要ありません。 もし私がこのようなプログラムを作るとしたら、入院患者と外来患者を区別するためのメンバをpatientクラスに持たせます。そしてコンストラクタの引数で入院/外来のどちらかを指定し、クラスのメンバにセットします。ienter_information()とoenter_information()は1つにまとめ、関数内部で入院、外来を判断し、それぞれの処理を行うようにします。同様に、charge_calc()も1つにまとめてしまいます。

libre
質問者

お礼

実は最初にclassを作ったときには"condition"という名前のメンバーがありましたが、入院患者と外来患者のリストを入力前から別々にするために敢えて今の方法にしました。今回は時間がないので出来ませんが、時間が出来次第、関数をまとめる方法も試したいと思います(明らかにその方がスマートですね)。 ありがとうございました!

libre
質問者

補足

只今、修正中です。しばらくお待ちください。 m(__)m

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.1

質問内容がいまいち理解できませんが...。 >4つの引数(days, rate, medi, service)を持つ関数と2つの引数(medi, service)を持つ関数(関数名は同じ)を別々に計算させたいのですが、main()から呼ぶときにそれぞれ4つと2つの引数を指定しないと「0個の引数を持つオーバーロードされた関数はありません」と怒られてしまいますよね? 0個の引数を持つ関数を定義していないのですから、当然の結果です。 >しかし、どう指定してよいのか分かりません。 4つの引数の関数を呼びたいのならば引数を4つ指定すればいいし、2つの引数の関数を呼びたいのならば引数を2つ指定すればいいです。ただし、引数の意味は私にはわかりませんが。 >classはpatient.hの中で定義しているのでmainからは見えませんよね? main.cppでpatient.hをインクルードしていれば見えます。そうでなければ見えません。必要ならインクルードしてください。

libre
質問者

お礼

ありがとうございます。

libre
質問者

補足

ようやく載せることが出来ますので、とりあえず全部載せます。 >4つの引数の関数を呼びたいのならば引数を4つ指定すればいいし、2つの引数の関数を呼びたいのならば引数を2つ指定すればいいです。 それは分かっています。 ただ、ienter_informationで入力した情報をここの引数として指定したいのですが、その方法が分からないという意味です。これで分かりますでしょうか? //mp101.cpp #include "patient.h" #include <iostream> #include <string> using namespace std; int main() { patient inp, outp; // 入院/外来患者 char which; static short icount = 0, ocount = 0; // 入院/外来患者数カウント double total; do { cout << endl << "'I'n-patient or 'O'ut-patient? (To quit, press 'Q'): "; cin >> which; if(which=='I') { icount++; inp.ienter_information(); total = inp.charge_calc(); cout << "Total: " << total << endl; } else if(which=='O') { ocount++; outp.oenter_information(); total = outp.charge_calc(); cout << "Total: " << total << endl; } else if(which=='Q') break; else cout << endl << "Invalid letter! Type I or O or Q." << endl; }while(which!='1' && which!='2'); return 0; } //patient.cpp #include "patient.h" #include <iostream> #include <string> using namespace std; patient::patient() { days=0; rate=0; } patient::~patient() { } void patient::ienter_information() { cout << "First name: "; cin >> fName; cout << "Last name: "; cin >> lName; cout << "Sex: "; cin >> sex; cout << "The number of days: "; cin >> days; cout << "The daily rate: "; cin >> rate; cout << "Medication charge: "; cin >> medi; cout << "Service charge: "; cin >> service; } void patient::oenter_information() { cout << "First name: "; cin >> fName; cout << "Last name: "; cin >> lName; cout << "Sex: "; cin >> sex; cout << "Medication charge: "; cin >> medi; cout << "Service charge: "; cin >> service; } double patient::charge_calc(short days, double rate, double medi, double service) { return (days * rate) + medi + service; //入院患者請求金額 } double patient::charge_calc(double medi, double service) { return medi + service; //外来患者請求金額 } //patient.h #ifndef PATIENT_H #define PATIENT_H #include <string> using namespace std; class patient { public: patient(); virtual ~patient(); void ienter_information(); void oenter_information(); double charge_calc(days, rate, medi, service); double charge_calc(medi, service); private: string fName; //first name string lName; //last name char sex; //sex short days; //the number of days spent in the hospital double rate; //the daily rate double medi; //charges for hospital services double service; //hospital medication charges }; #endif

関連するQ&A

  • C++の関数

    関数の課題が出たんですが分からないので教えてください。 第1引数と第2引数はchar型の1元配列であり、これら2つの配列(文字列)を連続して表示する関数catstringがあるものとする。 ただし第2引数にはデフォルトの文字列"あいうえお"が設定されている。main関数からキーボード入力で2つの文字列を取得し、 catstringの第1引数のみに文字列が渡される場合と第1、2引数ともに文字列が与えられるプログラムを作成せよ。 やってみましたがエラーが出てしまいます。 #include <iostream> #include <cstdlib> using namespace std; char catstring(char,char="あいうえお"); int main() { char a,b; cin>>a; cin>>b; cout<<catstring(a)<<endl; cout<<catstring(a,b)<<endl; return EXIT_SUCCESS; } char catstring(char x,char y) { char s; s=x+y; return(s); }

  • (C,C++言語)関数の引数は自動キャストされる?

    プログラミング言語C,C++の数値計算に関する質問です. 整数データ変数同士のみの計算結果は小数点以下は切り捨てられますよね. もし実数型で計結果を得たいときは,int変数を(double)や(float)でキャストしてあげなければならないことは知っています. ここで,仮引数リストにdouble型変数が設定されている関数の引数にint型変数を与えた時,関数の呼び出し時にキャストしなくても自動でキャストされるのでしょうか. 以下のサンプルコードを作成し,実行してみた結果を次に示します. ---サンプル--- #include <iostream> using namespace std; void printDouble(double val, double val2) { cout << "(double)val = " << val / val2 << endl; } int main(void) { for (int i = 1; i < 5; i++) { cout << i / (i * 2) << endl; printDouble(i,i*2); } } -----実行結果---- 0 (double)val = 0.5 0 (double)val = 0.5 0 (double)val = 0.5 0 (double)val = 0.5 ------------------------- 関数の外での計算は整数に丸められてしまうので i / ( i * 2 ) 計算結果はゼロに,関数の中では与えられた i はdouble型として扱われるので小数点以下の値も残っているということですよね. この場合,printDouble関数へ整数を与えるときには printDouble( (double)i , (double)( i * 2 ) ); といったようにわざわざキャストしなくても自動で仮引数の型でキャストされて関数が呼び出されると理解してもよいのでしょうか. 実行結果から明らかだろ,思われてしまうかもしれませんが,何かの参考書に記述されているのを見たり,人からそう教わったわけではなく,また関数のオーバーロードのこともありますので,質問させて頂きました.よろしくお願いいたします.

  • SystemC言語の文法(関数の引数にポインタ?)

    SystemC言語の文法について質問です。 ある雑誌で、ビット宣言変数のアドレスを関数に渡しており、 私も真似て作ってみたのですが、エラーが発生してしまいます。 --- (例) 引数にポインタを入れる処理 // 引数 sc_uint<32> *s の関数 void test::Calc_func( sc_uint<32> *s ) { cout << "s[0] = " << s[0]; // 32bitのデータ出力? } // これがmain文の代わりです void test::A_func(void) { sc_biguint<2048> a; sc_uint<12> i; for( i = 0; i < 2048; i++ ) { a[i] = 0; } Calc_func( &a[0] ); // ←問題! } // Error内容 Calc_funcの引数の入れ方が駄目! --- 色々、Calc_funcへの型を変えてやってみたのですが、 全くびくともしません。 雑誌が間違っている可能性は低いと思いまして、 今回、このような質問をさせていただきました。 インターネット上の情報でも、このような処理を 見つけることができませんでした。 どうぞよろしくお願いいたします。

  • C言語のポインタのプログラムについての質問です。

    C言語のポインタについて質問です。 nこの配列データaを受け取り、それらの値をもとに、2つのデータを引数で受け取って交換する関数void swap(double *a,*b)を用いることにより最終的に降順に並べ替えて出力したのち、それらを平均(average)と標準偏差(standard deviation)を引数で受け渡す関数 void calc_ave_stddev(int n,double a[],double *ave,double*stddev)を利用して出力されるプログラムを教えてほしいです。 main関数内での書式は printf("enter n:"); scanf("%d,&n"); for(i=0;i<n;i++){ printf("enter a[%d]:",i); scanf("%lf"&a[i]); } main関数での結果の出力は、 for(i=0;i<n;i++){ printf("a[%d]=%lf\n",a[i]); } printf("ave=%lf stddev=%lf\n",ave,stddev); です。

  • 関数の引数と実引数の取り扱いについて

    C言語初心者です. 関数の引数と実引数の取り扱いについて,教えていただきたいことがあります. 例えば,2変数の和を求める関数を考えると,以下のようになると思います. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; } このとき,mainプログラムでは,a,bふたつの変数を定義しておいて,関数sumに入れて計算させているわけですが,mainプログラムで変数x,yを定義しておいて,以下のようなプログラムにするのはありでしょうか? 参考書などをみると,前者のように取り扱っているようなのですが,試しに後者で実行させてみても同じ結果となりました. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; }

  • C++関数の仮引数について

    関数の引数に配列を指定したいのですが たとえば、 double* point[4]; void setPoint(double _point[]) { for(int i = 0; i < 4; i++){ point[i] = (_point + i); } } int main(void) { setPoint((double[])(1.0, 2.0, 3.0, 4.0)); } '型キャスト' : 'double' から 'double []' に変換できません。 とエラーが出てしまいます。 どのようにすればよいでしょうか?

  • printf関数の引数は文字例と決まっているからです。

    printf関数は文字列しか引数として受け取りません。 printf("文字列"); では数値を引数にしたらどうでしょう? #include <stdio.h> #main () {     printf(1);     return 0; } これはコンパイルエラーになります。printf関数の引数は文字列と決まっているからです。 この文章について質問です。 Q.なぜ上の「文字数」はダブルクォーテーションで囲まれているのに、下の「1」にダブルクォーテーションはないのでしょうか? Q.文書を見る限り、Cでは文字列と数値は区別されているように見えますが、なぜでしょうか?

  • +演算子オーバーロード

    こんにちは。お世話になっております。 // +演算子オーバーロード CPoint CPoint::operator+(CPoint& obj) //~(1) { CPoint tmp; tmp.m_x = m_x + obj.m_x; tmp.m_y = m_y + obj.m_y; return tmp; } int main() { CPoint point1( 100, 150 ); CPoint point2( 200, 50 ); std::cout << "x:" << point1.getx() << "y:" << point1.gety() << std::endl; point1 = point1 + point2; // オーバーロードされた+演算子が呼び出される std::cout << "x:" << point1.getx() << "y:" << point1.gety() << std::endl; point1 += point2; // オーバーロードされた+=演算子が呼び出される std::cout << "x:" << point1.getx() << "y:" << point1.gety() << std::endl; return 0; } 某サイトで上のようなサンプルプログラムがあるのですが これはc++で書かれた「+演算子オーバーロード」の定義で、動作としては 「point1 = point1.operator+( point2 ); // point1 = point1 + point2; と同じ」というような動作です。 それで疑問が出てきたのですが、イコールの右側で足す数が↓のような3つの場合、ans = a + b + c;です。 これだと(1)のところの引数を2つをとる関数を別に作らないとだめでしょうか?それとも、ans = ((a + b) + c);というふうに優先順位で自動的に計算してくれる+演算子オーバーロードのプログラムを教えてくれませんか?↑式のカッコは便宜上付けただけで、出来ればans = a + b + c;だけで計算出来るプログラムを教えてください。

  • printfの%fにおいて教本どおりなのにエラーが出ます

    本に書いてある通り、 ------------------------------------------------------------------ public class BreakTest { /** * @param args */ public static void main(String[] args) { int day = 1; double value = 1500; double rate = 1.05; System.out.println(day+"日目"); System.out.println("株価:"+value+"円"); System.out.println("上昇率:"+rate); while(value < 3000){ day++; value = value*rate; if(day >= 10){ break; } } System.out.println(day+"日目に"); System.out.printf("株価:%f円", value); } } ------------------------------------------------------------------ とプログラミングしたのに最後の文「System.out.printf("株価:%f円", value); 」 でエラーが出ます。エラーの内容は下記の通りです。 ------------------------------------------------------------------ Exception in thread "main" java.lang.Error: コンパイル問題が未解決です。 型 PrintStream のメソッド printf(String, Object[]) は引数 (String, double) に適用できません。 at BreakTest.main(BreakTest.java:24) ------------------------------------------------------------------ 何が間違っているのでしょうか?

  • 引数に二重配列のある関数について

    void calc(int *a,int b,int c){ a[0]=b+c; a[1]=b-c; } void main(void){ int x[2]; int y=2,z=5; calc(x,y,z); printf("x[0]=%d,x[1]=%d\n",x[0],x[1]); } 上のように引数が普通の配列の関数ならできるのですが, 引数が下のような多重配列になるとエラーが出てしまいできません。 void keisan(int **a,int b,int c){ a[0][0]=b+c; a[0][1]=b-c; a[1][0]=b*c; a[1][1]=b/c; } void main(void){ int x[2][2]; keisan(x,6,2); printf("x[0][0]=%d,x[0][1]=%d\n",x[0][0],x[0][1]); printf("x[1][0]=%d,x[1][1]=%d\n",x[1][0],x[1][1]); } 引数に多重配列を使った場合の関数の作り方について教えてください. お願いいたします.

専門家に質問してみよう