• ベストアンサー

C++について教えてください。(初心者です)

現在C++についての学習を進めているのですが、 2項演算子のオーバーロードで理解できないところがありますので、よろしかったらご教授ください。 //+をcoordクラスに対してオーバーロードする #include<iostream> using namespace std; class coord{ int x,y; public: coord() {x=0;y=0;} coord(int i,int j) {x=i;y=j;} void get_xy(int &i,int &j) {i=x;j=y;} coord operator+(coord ob2); }; //+をcoordクラスに対してオーバーロードする coord coord::operator+(coord ob2) { coord temp; temp.x = x + ob2.x; temp.y = y + ob2.y; return temp; } int main() { coord o1(10,10),o2(5,3),o3; int x,y; o3 = o1 + o2; o3.get_xy(x,y); cout << "(o1+o2) X:" << x << ",Y:" << y << endl; return 0; } この文の中で、o3.get_xy(x,y);というコードがありますが、 ここの部分がよくわからないのです。 そもそも、引数としてx,yがありますが、これはprivateメンバを 見に行きなさい。っと言っているのでしょうか? main()の中から直接使っている?? それとも?? すいません。この辺の理解が薄いようなので、2項演算子のオーバーロードとは関係ないかもしれませんが、教えてください。 よろしくお願いします。

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

  • ベストアンサー
  • hpsk
  • ベストアンサー率40% (48/119)
回答No.3

#2のhpskです。 noriemonさんはひょっとしてJava経験者でしょうか? > C++の場合は、変数を初期化しなくっても使えるっということなのでしょうか? 初期化していないとコンパイルエラーになるかどうか、ということならエラーにはなりません。 ただし、初期化されていない変数の値を参照したとき、その値は保証されません(気のきいたコンパイラは警告を出してくれます)。この点はCと同じです。 JavaやC#ではコンパイル時にエラーになります。 ただ、今回のプログラム例では、mainのx,yは値が参照される前にちゃんとした値が代入されてますから、上記の問題はありません。 Cの感覚だと、get_xyの呼び出しで渡しているのはxやyの値に見えますが、渡しているのはx,yへの「参照」であって、それが代入先になっているだけです。(このへんの見にくさがC++の文法の問題の一つでもあります) たとえば、coordクラスに void set_xy(int i,int j) {x=i;y=j;} のようなメンバ関数があって、これがmain内でx,yの初期化前に呼ばれると問題ですね。

noriemon
質問者

お礼

回答ありがとうございます。 そうです。まさに、CとJAVAの知識が混乱していたみたいです。やはり、教えていただいても、「参照」の扱いが難しいなぁ。なんて思ってしまいますが、、、 とにかく、的確な回答ありがとうございました。 またどうぞよろしくお願いします。

その他の回答 (2)

  • hpsk
  • ベストアンサー率40% (48/119)
回答No.2

main中の o3.get_xy(x,y); のx,yは、mainの先頭で宣言した、x,yを指しています。 このx,yを、coordクラスで定義されている、 void get_xy(int &i,int &j) {i=x;j=y;} の引数として参照渡ししています。 よってこのとき、get_xyの中のi,jはmain関数内のx,yを参照していることになります。 get_xy中に書かれているx,yは、coordクラス中でprivateで定義されている、x,yを指しています。今回の場合は、o3.xとo3.yですね。 結果として、main関数中のx,yにそれぞれo3.x、o3.yの代入されるわけです。 > 2項演算子のオーバーロードとは関係ない 直接関係ないですが、今後、演算子のオーバーロードを記述するにあたって、この辺りの理解は必要だと思います。

noriemon
質問者

補足

さっそくのお返事ありがとうございました。 もう少しだけ質問なのですが、 C++の場合は、変数を初期化しなくっても使えるっということなのでしょうか? それとも、こういう形で初期化をするっということなのでしょうか? すみません。頭がこんがらがってきました。 よかったら教えてください。

回答No.1

> この文の中で、o3.get_xy(x,y);というコードがありますが、ここの部分がよくわからないのです。 > そもそも、引数としてx,yがありますが、これはprivateメンバを見に行きなさい。っと言っているのでしょうか? ちがいます。 void coord::get_xy(int &i,int &j) {i=x;j=y;} なので ふたつの引数は 参照体。 o3.get_xy(x,y) はo3が持つ座標を x, y にセットして戻ってきます。 演算子オーバロードとはまったく関係ありません。

関連するQ&A

  • C++超初心者質問

    Visual C++ 2008 Express Edition Ver9.0.30729.1 SP を利用し、以下のプログラムを実行するための手順を教えてください。 Visual C++ 6.0では、ファイル>新規作成→ファイルTAB>C++ソースファイルのように、上記の場合はどのように進んだらよいのでしょう? ファイル>新規作成>プロジェクト→Win32 コンソール アプリケーション??? とすると、↓のエラーが出てしまいます。尚、VC2008をインストールしてから何も触っていません。 http://okwave.jp/qa4665322.html ソース #include<iostream> using namespace std; class coord{ int x,y; public: coord(){x=0;y=0;} coord(int i,int j){x=i,y=j;} void get_xy(int &i,int &j){i=x;j=y;} friend coord operator+(coord ob1,int i); friend coord operator+(int i,coord ob1); }; coord operator+(coord ob1,int i){ coord temp; temp.x=ob1.x+i; temp.y=ob1.y+i; return temp; } coord operator+(int i,coord ob1){ coord temp; temp.x=ob1.x+i; temp.y=ob1.y+i; return temp; } int main(){ char c[3]; // 画面固定のため coord o1(10,10); int x,y; o1=o1+10;; o1.get_xy(x,y); cout<<"(o1+10)X:"<<x<<",Y:"<<y<<"\n"; o1=99+o1;; o1.get_xy(x,y); cout<<"(99+o1)X:"<<x<<",Y:"<<y<<"\n"; cout<<"\nエンターで抜けます"<<endl; // 画面固定のため gets(c); return 0; }

  • プログラムの出力の説明を教えてください。

    出力が、画像のようになるのですが、最後に基本クラスのoperator=()が呼ばれるのがわからないです。 なぜ、そのようになるのか教えてください。 /* +,-,=をcoordクラスに関してオーバーロードし、 そのcoordをquadの基本クラスとして使用する */ #include <iostream> using namespace std; class coord{ public: int x, y; //座標 coord(int i = 0, int j = 0){ x = i; y = j; } void get_xy(int &i, int &j){ i = x; j = y; } coord operator+(coord ob2); coord operator-(coord ob2); coord operator=(coord ob2); }; //+をcoordクラスに関してオーバーロードする coord coord::operator+(coord ob2) { coord temp; cout << "coord operator+()を使用" << endl; temp.x = x + ob2.x; temp.y = y + ob2.y; return temp; } //-をcoordクラスに関してオーバーロードする coord coord::operator-(coord ob2) { coord temp; cout << "coord operator-()を使用" << endl; temp.x = x - ob2.x; temp.y = y - ob2.y; } //=をcoordクラスに関してオーバーロードする coord coord::operator=(coord ob2) { cout << "coord operator=()を使用" << endl; x = ob2.x; y = ob2.y; return *this; //代入先のオブジェクトを返す } class quad :public coord{ int quadrant; public: quad(){ x = 0; y = 0; quadrant = 0; } quad(int x, int y) :coord(x, y) { if (x >= 0 && y >= 0)quadrant = 1; else if (x<0 && y >= 0)quadrant = 2; else if (x<0 && y<0)quadrant = 3; else quadrant = 4; } void showq() { cout << "象限を示す:" << quadrant << endl; } quad operator=(coord ob2); }; quad quad::operator=(coord ob2) { cout << "quad operator=()を使用" << endl; x = ob2.x; y = ob2.y; if (x >= 0 && y >= 0)quadrant = 1; else if (x<0 && y >= 0)quadrant = 2; else if (x<0 && y<0)quadrant = 3; else quadrant = 4; return *this; } int main() { quad o1(10, 10), o2(15, 3), o3; int x, y; o3 = o1 + o2; //2つのオブジェクトの加算。演算子+()を呼ぶ o3.get_xy(x, y); o3.showq(); cout << "(o1+o2)X:" << x << ",Y:" << y << endl; o3 = o1 - o2; //2つのオブジェクトの減算 o3.get_xy(x, y); o3.showq(); cout << "(o1-o2)X:" << x << ",Y:" << y << endl; o3 = o1; //オブジェクトを代入する o3.get_xy(x, y); o3.showq(); cout << "(o3=o1)X:" << x << ",Y:" << y << endl; return 0; }

  • 派生クラスから基本クラスprotectedメンバへのアクセスについて

    C++初心者です。 以下のような基本クラスcoordと、その派生クラスquadがあり、quadクラスに関して=演算子をオーバーロードしました。 class coord { protected: int x, y; }; class quad : public coord { public: quad operator=(coord &ob2); }; quad quad::operator=(coord &ob2) { x = ob2.x; y = ob2.y; } するとob2からxにアクセスできないとエラーが出ます。 quadクラスのメンバ関数内なので、基本クラスのprotectedメンバにはアクセスできると思ったのですが、違うのでしょうか。 ご教授お願いします。

  • 演算子のオーバーロードについて

    []演算子のオーバーロードでつまづきました。 代入文で左辺、右辺、両方ともに[]演算子を使う場合 int &operator[](int i) { return a[i]; } int &operator[]のようにして、戻り値を参照型にしています。 このとき、main関数内で、 ob1[2]=ob2[2];(ob1,ob2はoperator[]関数が関連付けられているクラスのオブジェクト) のようにすると、左辺(ob1)にちゃんと代入されています。 つまりこの場合、main()関数内で、 (int &)型の(this->a[i])(元のオブジェクトは、ob1) に (int &)型の(this->a[i])(元のオブジェクトは、ob2)を代入しているのでしょうか?

  • C言語、行列の積を求めるプログラムについて

    「次に示す行列x,yの積を求めるプログラムを作成せよ。   x[2][3]={{1,2,3},{4,5,6}} y=[3][2]={{1,5},{5,3},{81}}」 という問題です。自分ではとりあえず、 #include<stdio.h> int main(void) { int i,j; int x[2][3]={{1,2,3},{4,5,6}}; int y[3][2]={{1,5},{5,3},{8,1}}; int xy[3][3]={0}; for(i=0;i<3;i++) for(j=0;j<3;j++) xy[i][j]=x[i][j]*y[i][j]; for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%3d",xy[i][j]); putchar('\n'); } return 0; } というプログラムを作ってみましたが、ダメでした。 ちゃんと積の表示が出るようにするにはどこをどう変えるべきでしょうか?

  • C言語 行列の積

    行列の積をfor文を使って計算したいです。 #include<stdio.h> int main(void){ int x[2][2]={{1,3},{2,4}}; int y[1][2]={3,2}; int xy[1][2]; int i, j, k; for (i = 0; i < 1; i++) { for (j = 0; j < 2; j++) { xy[i][j] = 0; for (k = 0; k < 2; k++) { xy[i][j] += x[i][k] * y[k][j]; } } } xの二行目の計算からできません。 プログラムの修正をお願いします。

  • C言語 プログラム 確率

    今、学校の授業で病気の感染プログラムを作っています。 内容は、 ・3カテゴリー(0:健康体、1:感染者、2:免疫体)の人間がいる。 ・2カテゴリー(0:病原体を持たない蚊、1:病原体ウイルスを持つ蚊)の蚊がいる。 ・人間と蚊がxy座標上をある速度でランダムに移動している。 ・健康体の人間とウイルスを持った蚊と人間ある一定距離内にいると蚊が人間を刺して病気が感染し、人間が0:健康体から1:感染者に変化する。 簡単に言いましたが、このようなプログラムを作っています。 その中で、人間に感染する部分のプログラムを下に載せます。 double c0x, c0y, ax, ay, bx, by; for(i=0; i<N;++i){ if(b[i].category==1){ c0x=(*cat0ka).coord.x; c0y=(*cat0ka).coord.y; ax=a[i].coord.x; ay=a[i].coord.y; bx=b[i].coord.x; by=b[i].coord.y; if(((c0x-ax)*(c0x-ax)+(c0y-ay)*(c0y-ay))<R){ (*cat0agent).category=1; } else if(a[i].category==1){ c0x=(*cat0agent).coord.x; c0y=(*cat0agent).coord.y; ax=a[i].coord.x; ay=a[i].coord.y; bx=b[i].coord.x; by=b[i].coord.y; if(((c0x-bx)*(c0x-bx)+(c0y-by)*(c0y-by))<R){ (*cat0ka).category=1; return ; } } int t; for(t=1; 7-t;++t ){ if((*cat0agent).category=1){ if(6<t){ (*cat0agent).category=2; } } } (*cat0agent).coord.x+=(frand()-0.5); (*cat0agent).coord.y+=(frand()-0.5); (*cat0ka).coord.x+=(frand()-0.5); (*cat0ka).coord.y+=(frand()-0.5); } } } このプログラムでは、一定距離内にいると100%感染するようになっていますが、 それを、"一定距離内にいると30~50%の確率で感染する"という条件に変えたいと思っていますが、そのやり方がわかりません。 どなかか分かりやすく丁寧に教えていただけませんか? お願いします。 ちなみに感染率は今30%で考えてもらえれば良いです。 載せたプログラム自体も完成しきれていないので、わからないかもしれません。 すみません。

  • C++ ソートのやり方

    僕が作ったプログラムで、これはバブルソートなのかわからないので教えてください。 また、ほかのソートの仕方も教えてください。 よろしくお願いします。 汎用関数を使っているのでわかりにくいかもしれないですがお願いします。 #include <iostream> using namespace std; template <class X>void Sort(X *data, int size) { X temp; for (int i = 0; i < size; i++){ for (int j = i + 1; j < size; j++){ if (data[i]>data[j]){ temp = data[i]; data[i] = data[j]; data[j] = temp; } } } } int main() { int i[10]{1, 4, 3, 5, 2, 10, 2, 7, 6, 8}; char c[10]{'c', 'b', 'z', 'a', 'x', 'y', 'j', 'n', 'm', 'r'}; Sort(c, 10); Sort(i, 10); for (int j = 0; j < 10; j++){ cout << i[j] << ' '; } cout << endl; for (int j = 0; j < 10; j++){ cout << c[j] << ' '; } cout << endl; getchar(); return 0; }

  • C#のインクリメント演算子のオーバーロード(前置きと後置き)

    インクリメント演算子をオーバーロードして、後置きインクリメントの場合に戻り値が演算前の結果を返すようにする方法はありませんか? class Sample {  public int x;  public int y;  public Sample(int x, int y)  {   this.x = x;   this.y = y;  }  public override string ToString()  {   return base.ToString() + " - x = " + x + ", y = " + y;  }  public static Sample operator ++()  {   x++; y++;   return this;  } } class EntryPoint {  public static void Main()  {   Sample sample = new Sample(1, 2);   // 「Sample - x = 2, y = 3」で、期待通り   Console.WriteLine(++sample);   // 「Sample - x = 3, y = 4」で、期待したのはインクリメントされる前の値である「「Sample - x = 2, y = 3」   Console.WriteLine(sample++);  } }

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

専門家に質問してみよう