- ベストアンサー
演算子のオーバーロード
座標を表すクラスとして class Point { public: double *buf; Point(double, double) { printf("new :%p ", buf); buf = new double[2]; buf[0] = x1; buf[1] = x2; printf("-\n"); } ~Point() { printf("delete :%p ", buf); delete [] buf; // ※1 printf("- \n"); } Point operator +(Point){ Point a(0.0, 0.0); a.buf[0] = this->buf[0] + p.buf[0]; a.buf[1] = this->buf[1] + p.buf[1]; return a; } Point operator =(Point){ this->buf[0] = p.buf[0]; this->buf[1] = p.buf[1]; return *this; // ※2 } }; int main() { { Point a(1.0, 2.0); Point b(3.0, 4.0); a = a+b; //(1) a = a+b+a+b; //(2) a = (a=b) + (b+b); //(3) printf("(%f, %f)\n", a.buf[0], a.buf[1]); } return 0; } を作成し、(1),(2),(3)のいずれかを記述して実行したところ、 (1) 正常に動作(4,6) (2) セグメンテーションフォルト ※1 を削除すると(8,12) (3) セグメンテーションフォルト ※1 を削除すると(9,12) という結果になりました。 Deleteで(同じアドレスを開放しようとして)失敗しているようなのですが、思った動作をさせるためにはどうすればよいでしょうか。 標準出力を載せたいのですが、文字数制限により無理のようなので、後ほど補足致します。 環境 Windows XP SP2 Cygwin 1.5.19(0.150/4/2) GCC 3.4.4
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ANO.2です。 Point operator+(const Point& p) ではなく、 Point operator+(const Point& p) const でした。 申し訳ありません。
その他の回答 (2)
- mizuneko
- ベストアンサー率16% (3/18)
jactaさんの言われるように、 コピーコンストラクタ定義したら動きました。 ただ個人的には、代入演算子の方が気になってしまいます。 参照をとって、参照を戻す形にしたほうがよいように思いますが、 どうでしょうか。 #include <stdio.h> class Point { public: double *buf; Point(double x1, double x2) : buf(new double[2]) { buf[0] = x1; buf[1] = x2; printf("new :%p -\n", buf); } Point(const Point& p) { buf[0] = p.buf[0]; buf[1] = p.buf[1]; } ~Point() { delete [] buf; printf("delete :%p -\n", buf); } Point operator+(const Point& p){ return Point(buf[0] + p.buf[0], buf[1] + p.buf[1]); } Point& operator=(const Point& p){ buf[0] = p.buf[0]; buf[1] = p.buf[1]; return *this; } }; int main() { Point a(1.0, 2.0); Point b(3.0, 4.0); a = a+b; a = a+b+a+b; a = (a=b) + (b+b); printf("(%f, %f)\n", a.buf[0], a.buf[1]); return 0; }
- jacta
- ベストアンサー率26% (845/3158)
あまり詳しく見ていないので、当て推量に近いですが... コピーコンストラクタが定義されていないのが直接の原因かと思います。 デフォルトのコピーコンストラクタでは、単にbufの値をコピーするだけで、領域は再確保しませんから、デストラクタで同じ領域を二重解放しているのでしょう。
お礼
恥かしながら「コピーコンストラクタ」という存在を初めて知りました。 まだまだ知識不足ですね… (コンストラクタで作成していないメモリ領域を開放しようとしているから変だな~と悩んでました) ご回答ありがとうございます。
お礼
いえ、ソースコード大変参考になりました。 参照で渡すとよいのですね。 自分の知識不足で、operator= の戻り値を参照にする点と > Point operator+(const Point& p) const という記述方法がなぜそうする(べきな)のかがちょっとわからないのですが、その辺は自分で調べてみます。 ご回答ありがとうございました。