- ベストアンサー
クラスや構造体のarrayを作成する方法とコンストラクタの引数渡し
- クラスや構造体のarrayを作成する方法とコンストラクタの引数渡しについて質問です。
- 質問1:コンストラクタ時、クラス内の変数へ引数の値を渡す方法について教えてください。
- 質問2:push_back時、クラスをインスタンスしてvectorに渡す方法についても教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
こんにちは。 > 今、自分が作成しているプログラムではクラス引数が10個近くあり、 クラスのメンバ変数が10個近くあるということでしょうか? 変数に関連性があるのでしたら、バラバラな変数にするよりも全部纏めて 一つの構造体にするのは如何でしょうか? 構造体にすれば、コンストラクタの引数で値を渡す場合でも一つの構造体 を渡せば済むと思います。 もっともその場合でも、引数に渡すための構造体を予め用意して、その 構造体に初期値を設定しておく必要はありますので、バラバラな引数に 値を渡すのと大して手間は変わらないかもしれません。 何れにせよ、何処かで初期値を設定する処理は必要だと思います。 ■サンプルソース ========================= #include <iostream> #include <string> #include <vector> using namespace std; //データ構造体の定義 typedef struct HOGE { string strName; int nData1; bool bData2; int nData3; int nData4; int nData5; } T_HOGE, *PT_HOGE; //== Testクラスの定義 == class Test { public: //メンバデータ T_HOGE m_tHoge; //コンストラクタ Test(T_HOGE &tHoge) : m_tHoge(tHoge){} //メンバデータ表示 void DispHoge(); }; //== Testクラスの関数(本体) == //メンバデータ表示 void Test::DispHoge() { cout << "Name = " << m_tHoge.strName << endl; cout << "Data1= " << m_tHoge.nData1 << endl; cout << "Data2= " << (m_tHoge.bData2? "True":"False") << endl; cout << "Data3= " << m_tHoge.nData3 << endl; cout << "Data4= " << m_tHoge.nData4 << endl; cout << "Data5= " << m_tHoge.nData5 << endl; } int main(void) { int i; T_HOGE tHoge; vector<Test> testObjArray; vector<Test>::iterator it; //testObjArrayへのデータ追加(1個目) tHoge.strName = "dog"; tHoge.nData1 = 1; tHoge.bData2 = true; tHoge.nData3 = 123; tHoge.nData4 = 1234; tHoge.nData5 = 12345; testObjArray.push_back(Test(tHoge)); //testObjArrayへのデータ追加(2個目) tHoge.strName = "cat"; tHoge.nData1 = 2; tHoge.bData2 = false; tHoge.nData3 = 234; tHoge.nData4 = 2345; tHoge.nData5 = 23456; testObjArray.push_back(Test(tHoge)); //testObjArrayのデータ表示 for(i=0, it=testObjArray.begin(); it!=testObjArray.end(); ++i, ++it){ cout << (i+1) << "個目:" << endl; (*it).DispHoge(); } //testObjArrayのデータ消去 testObjArray.clear(); return 0; } ========================= <実行結果> 1個目: Name = dog Data1= 1 Data2= True Data3= 123 Data4= 1234 Data5= 12345 2個目: Name = cat Data1= 2 Data2= False Data3= 234 Data4= 2345 Data5= 23456 以上です。
その他の回答 (4)
- Tacosan
- ベストアンサー率23% (3656/15482)
「クラス引数」って何でしょうか? さておき. 「内容の値も状況によりバラバラな為、このようなクラスの場合、初期化リストがあまり有効でないです。」 という状況では「コンストラクタで引数を受け取ってメンバ変数に代入する」しかないんじゃないかなぁ... というか, 直接代入できたとしても無意味な感じがします. 「直接代入できる」ためには「コンストラクタの引数とメンバ変数がそれなりに対応する」必要があるんだけど, もしそうなら初期化リストが使えるように思えるので. あと, 確かに「各メンバ変数に代入するためだけの関数」を作るのは変ですね. 値のチェックをするとか「与えられた値から各メンバ変数に適切な値を計算する」のならともかく, 値をそのまま代入するだけなら単純に代入した方がましだと思います. 結局のところ「tmp を作成する」の意味はやっぱりよくわからんのだなぁ.... #3 の最初の文の意味でいい?
お礼
「クラス引数」× 「クラスのコンストラクタ時の引数」○ です。 後、初期化リスト、の意味をデフォルト引数と勘違いしていました。 ちゃんと書いてくれていたのにごめんなさい。 おっしゃる通り、初期化リストの方が便利です。使えそうです。 「tmp を作成する」の意味は#3の最初で書いて頂いた文の意味であっています。 重ね重ねありがとうます。 かなり勉強になりました。
- Tacosan
- ベストアンサー率23% (3656/15482)
えぇと... やっぱり今一つ意味が分からんのだけど, ひょっとして「コンストラクタに渡した値を直接メンバ変数に設定できないか」ということ? つまり, 今の例だと Test(std::string sono1,int sono2,bool sono3) のようにできれば「いちいちメンバ変数に設定するだけの文を書かなくていい」から楽じゃんとか, そういうこと? もしそうなら, そんなことはできません. (コンストラクタを含む) メンバ関数にローカルな変数 (仮引数や局所変数) はクラス (のオブジェクト) が持つメンバ変数とは厳密に区別されますから, 「いったん仮引数で受け取り, その値を使ってメンバ変数を設定する」しかありません. ところで, Test(const std::string &tmp_sono1, int tmp_sono2, bool tmp_sono3) : sono1(tmp_sono1), sono2(tmp_sono2), sono3(tmp_sono3) { } のように const な参照を使ったり初期化リストを使ったりした方がいいと思うんだけど.... 今の場合については使わない理由もないし.
お礼
ありがとうございます。 今、自分が作成しているプログラムではクラス引数が10個近くあり、 内容の値も状況によりバラバラな為、 このようなクラスの場合、初期化リストがあまり有効でないです。 あと、setSono1,2,3等、値をセットする関数を書くと、引数の数が多い場合 プログラムがとても長くなってしまいます。そういう物なんでしょうか? (質問のプログラムの様に、コンストラクタ内で直接値をセットするのは 邪道?あまりしないのが普通ですか?) とりあえず指摘された場所を直してみました。 こんな感じで良いでしょうか? ================================ #include <string> #include <vector> class Test{ public: std::string sono1; int sono2; bool sono3; //コンストラクタ Test(const std::string &tmp_sono1,int tmp_sono2,bool tmp_sono3){ setSono1(tmp_sono1); setSono2(tmp_sono2); setSono3(tmp_sono3); } void setSono1(const std::string &tmp_sono1){sono1=tmp_sono1;} void setSono2(int tmp_sono2){sono2=tmp_sono2;} void setSono3(bool tmp_sono3){sono3=tmp_sono3;} }; int main(void){ std::vector<Test> testObjArray; testObjArray.push_back(Test("てすと1",1,true)); testObjArray.push_back(Test("てすと2",2,false)); return 0; } ================================
- Tacosan
- ベストアンサー率23% (3656/15482)
質問1 は意味がわかりません. 「tmp を作成する」とはどういうことでしょうか? 質問2 は... わざわざ new しなくてもいいのでは? new しなければメモリリークも起きえないのに.
お礼
testObjArray.push_back(Test("てすと1",1,true)); の形で渡せるんですね(^^; ありがとうございます。勉強不足でした。 「tmp を作成する」で言いたかったのは Test(std::string tmp_sono1,int tmp_sono2,bool tmp_sono3){… の様に、 一度「tmp_ほにゃらら」の各変数一度で受けてから それぞれ sono1=tmp_ほにゃらら; の様に内部変数に渡すしか方法がないのでしょうか? ということです。 説明不足ですいません。 他にも変な所があればご指摘して頂けると助かります。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
newしたインスタンスをdeleteしてませんけど、memory-leak起こしてませんか?
お礼
memory-leakは特に起こしていませんでした。 が、 確かにちゃんとdeleteしないといけませんね。 ありがとうございます。
補足
下の memory-leakは特に起こしていませんでした。 は memory-leakは起こしているかもしれませんが、 問題は出ていませんでした。 の誤りです。 ちゃんと正しくdeleteすべきです。
お礼
こんにちは。 >クラスのメンバ変数が10個近くあるということでしょうか? 「クラスのコンストラクタ時の引数」の意味のつもりでした。 言い方的に正しくなかったです。 混乱させてしまいすいません。 非常に分かりやすくサンプルコードまで書いて頂き、 ありがとうございます。 これを参考にもう一度自分のコードを組み直してみます。