- ベストアンサー
operator=()のオーバーロード。
C++で簡単な多次元ベクトルを扱うクラスをつくっているのですが、 operator=()の実装で躓いてしまいました。 過去ログでは void operator=(CHoge& hoge){ (略) } という実装のアドバイスを見つけられたのですが、 これではa = b = c;といったような代入ができません。 結局*thisを返すように実装しているのですが、うまくいかない原因がどうしてもうまくいかないので、どなたか教えていただけないでしょうか? --------------------------- Windows XP SP2 Microsoft Visual Studio.net theSpokePremium version --------------------------- class vector{ public: /* (中略) */ vector(int dimensions) : d(dimensions) { v = new double[d]; for(int i = 0; i < d; i++){ v[i] = 0.0; } } /* (中略) */ void set(int dimension, double x) { v[dimension] = x; } int size() { return d; } /* (中略) */ vector operator=(vector& right) { if(right.d != d) return INVALID_VECTOR; for(int i = 0; i < d; i++){ v[i] = right.v[i]; } return *this; } /* (中略) */ private: int d; // ベクトルの次元 double *v;// 各成分 } --------------------------- int main() { vector a(3); // a(0.0, 0.0, 0.0) a.set(0, 1.0); // a(1.0, 0.0, 0.0) vector b(3); // b(0.0, 0.0, 0.0) b.set(1, 2.0); // b(0.0, 2.0, 0.0) b = a; for(int i = 0; i < b.size(); i++){ printf("%f ", b.get(i)); } printf("\n"); return 0; } ---------------------------
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
No.1です。 おおぼけ。 > return &*this; < return *this; 参照は値と同じ記述でしたね。 # ちょっと書いてないと記述が危うくなる
その他の回答 (3)
- ddnp009
- ベストアンサー率25% (15/58)
operator=()の実装については、#1さんと#2さんの 回答どおり、すなわち参照として*thisを返すこと。 コトバの意味がはっきりしていません。 >多次元ベクトル どこが多次元なんですか?配列のラッパーにしか見えない。 要素がdouble固定ということは、各要素の型が class vectorではないのですよね。 >うまくいかない原因がどうしてもうまくいかない 落ち着いて、投稿する前に読み直してみましょう。 そもそも、どのように動いて欲しいのか不明。 最後に、あえてstd::vectorを使わずに 自前のvectorを書いているのは勉強のためですよね?
お礼
> どこが多次元なんですか?配列のラッパーにしか見えない。 そうですね。この部分だけだと単なるラッパーですが、多次元配列ではなく「数学の」多次元ベクトルクラスとして完成させたいと思っています。 #1さんへの補足としてリンクを貼りましたが、少しづつ数学演算を追加していきます。 > 落ち着いて、投稿する前に読み直してみましょう。 > そもそも、どのように動いて欲しいのか不明。 確かに日本語がおかしいですね、整形しようとしてるうちにおかしくなってしまったようです。。 読みづらい文章で申し訳ありません。 知りたいのはoperator=()の正しい実装という一点、動作はベクトル各要素への代入です。 →for(int i = 0; i < d; i++) v[i] = right.v[i]; 最後に、 > あえてstd::vectorを使わずに > 自前のvectorを書いているのは勉強のためですよね? 目的の半分は勉強、 残り半分は自前の数学演算クラスが欲しいからです。 数学という前提があればstd::vectorではあんまりなので。 確かに自分の言葉足らずでした。 今回は既にご回答をいただくことができましたが、 以後気を付けるようにします。 回答ありがとうございました。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
回答は既にある通りですが、ちょっと補足を。 a = b = c; という記述は、見かけ上、a と b に c を代入しているように見えますが、= は、 + や - と同じ2項演算子です。 ですから、 a = b = c; は、 a = (b = c); という意味です。 つまり、 1)b に c を代入する。その代入式の値は c 2)a に、(b = c) の結果を代入する。 という2段階の動作が(意味的には)発生します。 このために、このような操作を行うためには、operater=() は、operater=() の引数に変換可能な型を返す必要があります。 つまり、 vector& operator=(vector& right); となるわけですね。
お礼
> という2段階の動作が(意味的には)発生します。 ここまでは理解できていたのですが・・・。 その先がまだまだ理解不十分でした。 ありがとうございます。
- rinkun
- ベストアンサー率44% (706/1571)
連続代入するには代入演算子はオブジェクトへの参照を返さないといけません。 基本的には vector& operator=(vector& right) { /* 中略 */ return &*this; } のような記述にすると思います。
補足
800字制限で補足ができませんでした。 といってももう返答をいただいてしまいましたが・・・。 ---------------------------[実行結果] -26569842580370804000000000000000000000000000000000000000000000000000000000000000000000000.000000 -26569842580370804000000000000000000000000000000000000000000000000000000000000000000000000.000000 -26569842580370804000000000000000000000000000000000000000000000000000000000000000000000000.000000 --------------------------- [プログラム全体] http://www.geocities.jp/bethrned/vector.h.html http://www.geocities.jp/bethrned/test.cpp.html --------------------------- よろしくお願いします。
お礼
#1へのお礼も兼ねて。 ありがとうございます。 解決しました。 C++の参照がまだいまいち理解しきれてないので勉強して出直してきます。