c++でのクラス設計について

このQ&Aのポイント
  • c++で色を表すクラスを作成する際に、色の成分を参照する方法について悩んでいます。
  • 現在は配列を使用して成分を参照しているが、見やすさを考慮して、クラス内で成分を参照する方法を模索している。
  • 参照変数を使用する方法も考えているが、コンパイルエラーが発生している。
回答を見る
  • ベストアンサー

c++でのクラス設計について

 今,c++で色を表すクラスを作っています.  色とはいっても,RGBやXYZなどいろいろな色がありますよね?もし,「各成分の合計を求める」なんて言う関数を作ろうと考えるとすると(必要ないですが^^…)RGBに対しても,XYZに対しても,というように2つ以上作るのは面倒です.そこで,n成分を持つ色のクラスというものを作って,そのクラスを継承して,RGB, XYZなどを表せないかと考えました.  つまり… class color3{ double data[3]; ~~~~~~ }; class rgb : public color3{ ~~~~~~ }; class xyz : public color3{ ~~~~~~ }; (実際color3はtemplateクラスで,double data[3]もポインタを使って要素数を変更できるようにしています.) もちろんこの方法で正常に動いていますが….これではrgbクラスの変数cを宣言して,成分を参照するときに,赤色ならc.data[0],緑色ならc.data[1]というように,data[~]で参照しなければなりません.しかし,これでは見にくいと思っています><.できるなら赤色ならc.r, 緑色ならc.gというように参照したいです.もちろん派生クラスの中にdouble r, g, b; と宣言すればいいのですが… .そうしてしまうと,一番最初の目的が達成できません.ポインタを使ったり,メンバの値を取得する関数(getR(), getX()みたいな…)を作れば解決できますが,この方法を使うと*(c.r), c.r()のような参照をしなければならず,「c.r」というようなきれいな参照はできません.贅沢を言っているようではありますが.c.rと表せるようなクラスの設計の仕方はあるでしょうか?  現在ぼんやりと考えているのは class color3{ double data[3]; ~~~~~~~ }: class rgb : public color3{ double &r = data[0]; double &g = data[1]; double &b = data[2]; ~~~~~~ }; class xyz : public class3{ ~~~~~~ }; のように,参照変数を使えないか,と思っています.もちろん上の方法ではコンパイルエラー となりましたが><  質問が長くなってしまいすいません><  よろしくお願いします. 必要ないかもしれませんが参考までに… 【環  境】MaxOS 10.6 【言  語】c++ 【開発環境】Xcode 【 レベル 】プログラミング歴6年 c歴4年 c++歴1年の大学1年です

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

  • ベストアンサー
回答No.1

これ↓ではいかがです? #include <iostream> using namespace std; class color3{ public: double data[3]; }; class rgb : public color3{ public: double &r; double &g; double &b; rgb() : r(data[0]), g(data[1]), b(data[2]) {} }; int main() { rgb x; x.data[0] = 1.23; cout << x.r << endl; x.g = 4.56; cout << x.data[1] << endl; }

hira_kazu
質問者

お礼

 試してみると,上手くいきました(^^)/  コンストラクタを使うって言う感覚が頭になかったです><  これでわかりやすく表せそうです^^  ありがとうございました

その他の回答 (2)

  • qwertfk
  • ベストアンサー率67% (55/81)
回答No.3

class color3 { public:  virtual double* data() = 0;  double& data(int idx) { return data()[idx]; } }; class rgb : public color3 { public:  double r, g, b; public:  virtual double* data() { return &r; } }; class xyz : public color3 { public:  double x, y, z; public:  virtual double* data() { return &x; } }; これでも大体要求を満たせるのではないかと思うのですが、いかがでしょうか。

hira_kazu
質問者

お礼

 仮想メンバを使うって言う手があったんですね.  1度試してみます^^  回答ありがとうございました

回答No.2

クラスを設計するとき、特に何かを継承するとき、「本質的な部分は何か?」というのを常に意識しなければなりません。 この例だと、そもそも、color3 というクラスは何者でしょうか? 色を表す基底クラスですか? だとすると、どのあたりが「色」の性質なのでしょう? もし、本当に「色」を表すものなら、色としての本誌的な情報を持っているはずなので、これを継承する rgb などのクラスと相互に変換できる必要があるでしょう。 もしかしたら、これは、単なる「N個の数値に関するいろいろな演算をまとめた」クラスかもしれません。 この場合だと、いろいろな色を表すのに共通して使うかもしれませんが、「色」ではありません。 この場合、直接継承するのではなく、メンバーとして持つほうが間違いがありません。 calss color3 // たぶん、名前は変えた方がいい { }; class rgb { private: color3 basicList; public: double r; double g; double b; } です。 また、本当は、「色」という機能を持った場合、r の値を変更するといろいろと副作用があるはずです。 全体としての明るさが変わるとか。 そういうつじつまあわせを確実に行うためには、r, g ,b を public: なメンバーにするよりも、getter や setter 経由で使う private: なメンバーにしておく方が安全です。 また、共通の「色」のクラスから継承したとしても、r, g b, というものをあからさまにしてしまう時点で、x, y, z とのインターフェイスは、完全に同じというわけにはいきません。 このあたり、何を本質的とするか、何を固有のものとするかというのも考えるべきところです。

hira_kazu
質問者

お礼

 やはり要素はprivate:で宣言しておいた方が,安全なんですね.いつもめんどくさがってpublic:で宣言してしまうので気をつけなければなりません><  回答ありがとうございました

関連するQ&A

  • C++ のクラスの定義

    C++の初心者です。 C++のことでお聞きしたいことがあります。 namespace test1{ class A { friend class B; protected: int a; }; } とtest1の下にAクラスを作り namespace test2{ class B { public: test1::A A1; }; } と別のnamespaceにBというクラスを作り、 A1というAのインスタンスを持ちたいのです。 しかし、Aというクラスを先に宣言しているので Bというクラスが解らないらしく friendがうまく働きません。 friend class test2::B としても test2がまだ宣言されていないので、 ????とコンパイルエラーが出ます。 先にtest2::B を宣言してしまうと、 今度はtest1::Aが解らずに エラーが出てしまいます。 こんな場合はどのように書けばよろしいのでしょうか? 環境はwindows2000でVC++ 6.0です。 どうか宜しくお願いいたします。

  • C++でこんなクラスを作りたい。

    以下のようなことをしたいと思っています。C++初学者です。 長いかもしれませんがずっと悩んでいます。 いま  w(x) = ap(x) + bq(x) + cr(x) + ..... のような式を計算機実験でメインに扱おうと思っています。 項の数は時によりけりです。 (a,b,cは係数、p,q,rは関数です) それぞれのp,q,rは同じ構造をした式であり、また係数a,b,cを p,q,rの付属物だと考えてcomponentというクラスのインスタンスにしました。 class component{ //メンバ変数 double a //係数 mathvec mu //平均値,mathvecは自作の加減法などができるベクトルのクラス double sigma //分散 //メンバ関数は割愛 } な感じです。 さて、それで上であげたw(x)のような関数が何種類か登場するので 同じ式に属するcomponentのインスタンスをグループ化するようなクラスをつくりたいのです。 w = ap + bq + cr z = ku + mv + ng を扱うのならばとりあえずp,q,r,u,v,gを宣言した跡に mixture mix1(p,q,r); mixture mix2(u,v,g); のようにできるmixtureというクラスを作りたいのです。 それで mix2.at(0)->method(); (u.method()と同じ感じ) みたいな操作ができるとうれしいです。 自分で少し考えたのはmixtureがcomponent*を格納する STLのvectorをもつようにすればいいかなと思いましたが どうもコンパイルエラーがぜんぜん取れず困っております。 class mixture{ private: vector<component *> vec; public: mixture(int num, ...);  //numはp,q,rなどの個数 component *at(int num); //numは何番目の要素を返すか }; mixture::mixture(int num, ...){ va_list ap; va_start(ap,num); for(int i=0;i<num;i++){ vec.push_back(va_arg(ap,component&); } } component* mixture::at(int num){ return vec.at(num); } お願いします! 特にISO C++ forbids declaration of vector with no type みたいなエラーがまず出ます。コンパイラはg++です。

  • builder5とvisual C++の違い

    builder5で2次元の配列にそれぞれr,g,bの変数が存在するという宣言を以下のように作っていたのですが、これと同じ宣言をvisual C++で書こうとしているのですが、上手くできません。 struct{ Byte r; Byte g; Byte b; }rgb[10][10],rgb2[10][10]; //マス数は10×10までとする visual C++では、どう書けばいいのでしょうか? 回答よろしくお願いします。

  • ベンツCクラスの色

    ベンツのCクラス・アバンギャルドの購入を考えております。 色は「カルサイトホワイト」か「イリジウムシルバー」のどちらかにしたいと思うのですが、 それぞれの色のメリット、デメリットを教えて頂けないでしょうか。 特に「カルサイトホワイト」にした場合、 普段の手入れの方法やコーティングを施す頻度等も教えて頂ければ助かります。 使用目的は主に買い物等の普段使いで運転する家族は30代~40代の男女です。 よろしくお願い致します。 [参考] Cクラス・カラーバリエーション(ヤナセ) http://www.yanase.co.jp/mercedes-benz/c-class/color_sedan.asp

  • C,C++,C++/CLIの構造体とクラス

    C++の構造体・クラスって、メンバのアクセス指定子のデフォルトが privateかpublicかという違い「だけ」しか全くないのでしょうか? クラスにおける value class / ref class という分類はC++/CLIのもので これについては value class の方は C言語の構造体に近いという事でいいでしょうか? ref classの方は ネイティブのC++のクラスを マネージ用にしたようなもので C++/CLIの構造体は C++のそれと同じで OKですか? そしてそれらの構造体には、値型・参照型といった分類はないのでしょうか?

  • [C++/CLI] アンマネージクラスの中でマネージクラスを使用したい。

    イベント駆動型のライブラリを使用しているプログラムのC++/CLIへの移行で困っています。 イベントの基底クラスAがC++の構文で書かれているため、派生クラスBはclassで宣言するようにコンパイラからエラーが帰りました。 ですので、classと宣言すると今度はアンマネージクラスの中でマネージコードは使用不可能といわれました。 どうにかこの現象を回避する方法はありませんか? class A : ライブラリで宣言されているイベントハンドラ(変更不可能) ref class B : A{} と宣言するとref classは使えないとエラー class B : A{} と宣言するとマネージコードが使用できないとエラー

  • C++でクラスのインスタンス化が参照

    他の人のC++ プログラムを見ているのですが、 クラスをインスタンス化する部分で CLASS_CAR car; CLASS_TRAIN &train; のように書かれているのですが 後者の意味が分からないのですが、これは何をしているのでしょう? 引数なら 元の変数のエイリアスを宣言するところなのでしょうが、  これだと 何に対するエイリアスだか分からず 困っています。

  • visual C++でのグローバル変数の宣言

    visual C++でマスの色を読みとって、いろいろな処理を行うプログラムを作成中なのですが、グローバル変数として以下の宣言をしたときに、以下のエラーが出ます。 struct{ int r; int g; int b; }rgb[10][10]; //マス数は10×10までとする error C3183: マネージ型 'SOMsample::Form1' の中で名前のないクラス、構造体またはユニオンを定義することはできません。 これをbuilder5で書き込んだときはエラーが出なかったのですが、visual C++ではどう書けばいいのでしょうか? 回答よろしくお願いします。

  • C++で参照カウンタを実装したいのですが

    こんにちは。 C++でクラスに参照カウンタを実装したいのですが、もしも実装する場合、 class CRefCounter {   参照カウンタとAddRef、Releaseメソッドを仮想メソッドとして実装 }; このクラスを継承して直接使う方法と、 class IRefCounter {   参照カウンタとAddRef、Releaseメソッドを純粋仮想メソッドとして宣言 } このクラスを継承して継承側で実装する方法とがあると思うのですが普通はどちらを使うものでしょうか?

  • C++ クラス名の前のdefine

    C++ クラス名の前のdefine 初めまして、質問させてください。 C++の作法?でクラス宣言時にクラス名の前につけるdefineには なんお意味があるのでしょうか? コード例 #define DEFINE class DEFINE Hoge{ }; 以上になります。 ご教授宜しくお願い致します。

専門家に質問してみよう