- ベストアンサー
基本クラスのポインタから、特定の派生クラスのメンバ変数を変更する方法?
VC++でプログラミングをしています。 A(基本クラス) A1, A2, A3, ...(派生クラス) を作成しました。A1,A2,A3, ...は、Aの派生クラスです。 このとき、基本クラスAのポインタから、特定の派生クラスにのみ存在するメンバ変数m_dataのみ変更したいのですが、存在するかどうかをどのように判定して、値を変更すれば良いでしょうか? できれば、下記のような構造でループできるとありがたいです。 A* a[100] (その後、a[100]に、派生クラスA1,A2,A3,..を割り当て、 それらが、混在しているとします。) for(i=0 ; i<100 ; i++){ if(a[i]->m_dataが存在する場合){ (2) a[i]->Set_m_data("m_dataの新しい値") (1) } } (1)は、a[i]->m_data = "m_dataの新しい値" でも良いです。 現状では、m_dataがメンバでない派生クラスがあるので、 (2)のif文の判定自体ができず困っています。 よろしく御願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
言語仕様的はメンバ変数の存在を確認する方法は無いです。 (処理系依存でも良いならば全く無いわけではありませんが…) よって別のアプローチで (1)仮装関数を利用して別個に処理させる class A{ public: virtual Set_m_data(M_DATA &Adata){ //何も入れない。空の処理 } }; class A1{ //メンバ無し public: //何も作らない }; class A2{ //メンバ有り private: M_DATA m_data; public: virtual Set_m_data(M_DATA &Adata){ m_data = Adata; } }; //代入処理 for(i=0 ; i<100 ; i++){ a[i]->Set_m_data(m_dataの新しい値);//チェックする必要もない } (2)基底クラスAにm_data型のポインタを用意してそれで判別 class A{ public: M_DATA *pm_data: A(){//コンストラクタ pm_data = NULL; //NULLならばデータ無し } }; class A1{ //メンバ無し public: //何も作らない }; class A2{ //メンバ有り private: M_DATA m_data; public: A2(){//コンストラクタ pm_data = &m_data; //NULLでない場合はデータ有り } }; //代入処理 for(i=0 ; i<100 ; i++){ if(a[i]->pm_data){//ここがNULLならばメンバ無しと判定できる *(a[i]->pm_data) = m_dataの新しい値; //そのまま代入も可能 } }
その他の回答 (2)
- postal0x02
- ベストアンサー率42% (24/57)
派生クラスにオーバーライドさせてはどう? Set_m_data() は共通の呼び出しみたいだし・・・ class A { public: virtual void Set_m_data( m_dataの型 ){} }; class A1 : public A { }; class A2 : public A { private: m_dataの型 m_data; public: void Set_m_data( m_dataの型 a ) { m_data = a; } }; A1 は m_data を持ってない。 A2 は m_data を持っている。 呼び出すときは、 for(int i=0 ; i<100; i++) { a[i]->Set_m_data("m_dataの新しい値"); } ちなみに virtual void Set_m_data( m_dataの型 ){} ↓こっちでもOK virtual void Set_m_data( m_dataの型 )=0; 違いは virtual void Set_m_data( m_dataの型 ){} 派生クラスは Set_m_data() を実装しなくてもよい virtual void Set_m_data( m_dataの型 )=0; 派生クラスは Set_m_data() を実装しなければならない
お礼
実装しましたところ、うまく行きました!! m_dataのない派生クラスには新しい変数やデータを付加する必要なく、 ループでも条件分岐が必要なくなったので、高速に処理できました。 本当にご教示どうもありがとうございました。 今後ともよろしく御願いします。
補足
ご教示ありがとうございます。基本クラスに仮想関数を作成する方法が非常に良く分かりました。この方法ですと、派生クラスに当該メンバがあるかどうかを判定する必要がないですし、m_dataを持っていないクラスにメンバを追加する必要もないので、非常にコンパクトですばらしい方法だと思いました。明日、早速、実装してみます。今後ともご教示よろしくお願いします。
- jacta
- ベストアンサー率26% (845/3158)
クラスAに仮想関数がひとつでも含まれるのであれば、dynamic_castを使えば、ポインタの参照先が特定の派生クラスのものかどうかを判定できます。 m_dataが存在するかどうかを直接判定するには、それを調べるためのメンバを追加せざるを得ないでしょう。
お礼
ご教示ありがとうございます。今のところ仮想関数はないのですが、作成を検討してみます。m_dataが存在するかどうかを直接判定するには、それを調べるためのメンバを追加せざるを得ないのですね。クラスをできるだけコンパクトにしたかったので、不要なメンバはできるだけ作成したくなかったのですが、他に方法がないようであれば、クラスA及びその派生クラスに判定のためのメンバを追加することを検討してみます。どうもありがとうございました。
お礼
ご教示ありがとうございました。 今回は、条件分岐が不要な(1)の方法を採用してみました。 実装しましたところ、うまく行きました!! m_dataのない派生クラスには新しい変数やデータを付加する必要なく、 ループでも条件分岐が必要なくなったので、高速に処理できました。 本当にご教示どうもありがとうございました。 今後ともよろしく御願いします。