動的オブジェクト取得(動的メモリ取得)
- ほしいメモリの型と数を考える
- ほしい型のポインタ変数を用意し初期化(エラーが起きたときわかりやすいようにnullptrを代入しておく)
- メモリを確保する(new演算子を使うと、メモリを確保してその先頭アドレスが返ってくる)
- 用意したポインタ変数に返ってきたアドレス(確保したメモリの先頭アドレス)を代入する
- (おいしくいただく)
例として、floatの配列を動的に取得するサンプルをしまします。
大凡上で示した手順のままです。
#include <iostream> using namespace std; int main() { int num; cin >> num; //配列数をキーボードから入力 float *parr = nullptr; //何もささないアドレスで初期化 //num個のfloatのメモリを確保して先頭アドレスを返す parr = new float[num]; //値をデータ数分読み込み for(int i=0;i<num; i++) //cin >> parr[i]; cin >> *(parr + i); //アドレスを使ったかきかたでやってみて //データ数分の値を表示 for(int i=0;i<num;i++) //cout << parr[i] << endl; //ポインタを使ったかきかたで表示! cout << *(parr+i) << endl; }
メモリの後片付け
説明するの忘れてた!
動的にクラスのインスタンスを作る
クラスのインスタンスに対しても、同じようにできます。
ただし、配列として複数個分のメモリを取得するときにはちょっと面倒なことが起こります。
まず、1個のインスタンスを動的に確保して使ってみる。
#include <iostream> #include <string> using namespace std; class student { private: string name_; int kokugo_, sansu_; public: student(string _name, int _kokugo, int _sansu); void SetName(string _name){ name_ = _name;} void SetKokugo(int _kokugo){ kokugo_ = _kokugo;} void SetSansu(int _sansu){ sansu_ = _sansu;} string GetName(){return(name_);} int GetKokugo(){return(kokugo_);} int GetSansu(){return(sansu_);} void PrintMe(); //コンストラクタとゲッターセッターを準備 }; student::student(string _name, int _kokugo, int _sansu) :name_(_name), kokugo_(_kokugo), sansu_(_sansu) { } void student::PrintMe() { //メンバの値を表示 cout << "name : " << name_ << endl; cout << "kokugo: " << kokugo_ << endl; cout << "sansu : " << sansu_ << endl; } int main() { student ymd("yamada", 80, 60); ymd.PrintMe(); student *pYmd = nullptr; pYmd = new student("yamada2", 90, 100); }
デストラクタとオブジェクトの動的配列
オブジェクトを動的に配列で取得すると、引数付きのコンストラクタは呼べない!
引数無しの、デフォルトのコンストラクタだけが呼び出し可能です。
コンストラクタの逆をやるのがデストラクタ!
#include <iostream> #include <string> using namespace std; class student { private: string name_; int kokugo_, sansu_; public: student() //コンストラクタ :name_(""),kokugo_(0),sansu_(0){cout << "俺誕生" << endl;} student(string _name, int _kokugo, int _sansu); ~student(){cout << "俺終了" << endl;} //デストラクタ void SetName(string _name){ name_ = _name;} void SetKokugo(int _kokugo){ kokugo_ = _kokugo;} void SetSansu(int _sansu){ sansu_ = _sansu;} string GetName(){return(name_);} int GetKokugo(){return(kokugo_);} int GetSansu(){return(sansu_);} void PrintMe(); //コンストラクタとゲッターセッターを準備 }; student::student(string _name, int _kokugo, int _sansu) :name_(_name), kokugo_(_kokugo), sansu_(_sansu) { } void student::PrintMe() { //メンバの値を表示 cout << "name : " << name_ << endl; cout << "kokugo: " << kokugo_ << endl; cout << "sansu : " << sansu_ << endl; } int main() { //student ymd("yamada", 80, 60); //ymd.PrintMe(); student *pYmd = nullptr; string namae; int koku,san; //cin >> namae >> koku >> san; //pYmd = new student("yamada2", 90, 100); pYmd = new student[2]; pYmd[0].SetName("yamada"); pYmd[0].SetKokugo(60); pYmd[0].SetSansu(80); pYmd[1].SetName("Ueda"); pYmd[1].SetKokugo(80); pYmd[1].SetSansu(90); //pYmd->PrintMe(); //名前とか、点数を書き換えて、表示してみて //pYmd->SetName("Ueda"); //pYmd->PrintMe(); pYmd[0].PrintMe(); pYmd[1].PrintMe(); delete [] pYmd; }