「オブジェクトポインタ,newとdelete」の編集履歴(バックアップ)一覧はこちら

オブジェクトポインタ,newとdelete」(2016/03/23 (水) 13:25:37) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*オブジェクトポインタとは ※こちらも参照 [[オブジェクト]] 通常のポインタと同様、クラスに対してもポインタで扱うことができる。 クラス型のポインタpはobjを指すようになる。 Person obj; Person *p = &obj; ポインタの場合、各変数や関数にアクセスする時は 下の例のように->(アロー演算子)を使用する。 p->age; p->selfIntroduction(); *メモリの動的確保と解放(malloc & free、 new & delete) **new 演算子 C、C++の配列は動的な配列の確保ができない。 new演算子を使うとメモリの動的確保が可能になる。 new,deleteはC++ の演算子なのでincludeの必要はない。 cの<stdlib.h>にあるmalloc と freeでも使用可能 ただし、演算子オーバーロードが使えない、コンストラクタ、デストラクタが呼び出せないため、C++ではnew と deleteを使う。 例: double a[10]; // 静的な確保はOK int n; cin >> n; // キーボードから入力 double b[n]; // NG コンパイルエラーになる  mallocの詳細 形式: #include <stdlib.h>   void *malloc(size_t size); 機能: 大きさsizeのメモリ領域を確保する。 引数: size: 確保したいメモリのバイトサイズ。 返却値: 成功した時:確保したメモリブロックを示すポインタ 失敗した時:NULL 例1:mallocによる動的確保とfreeによる領域解放 #html2(){{ <pre class="brush: cpp;"> #include < iostream > using namespace std; int main(void) { int *ip; /* 割り振られた領域のアドレスを格納するためのint型のポインタipを宣言 */ int n; /* 確保する要素数を入力 */ cout << "要素数を入力してください: " <<endl; cin >> n; ip = (int *)malloc(n * sizeof(int)); /* メモリ領域の確保 */ for (int i=0; i < n; i++){ ip[i] = i; } for (int i=0;i < n; i++) cout<< ip[i] << endl; free(ip); /* 確保したメモリ領域の解放 */ return 0; } </pre> }} 例2:newによる動的確保とdeleteによる領域確保 #html2(){{ <pre class="brush: cpp;"> #include < iostream > using namespace std; int main(void){ int n; cin >> n; int * b = new int[n]; // b を確保 for(int i=0; i < n; i++){ b[i]=i; } for(int i=0; i < n; i++){ cout<< b[i] << endl; } delete[] b; // b を解放 return 0; } </pre> }} *二次元配列の場合の動的確保 通常の二次元配列(b[][])だと動的確保ができないので、ポインタ配列を使って擬似的に作り出します。 以下がソースコードです。 #html2(){{ <pre class="brush: cpp;"> #include < iostream > using namespace std; int main(void){ int n,m; cin >> n; cin >> m; //二次元の時はダブルポインタ(** a)を使用 double ** a = new double*[n]; //n個のポインタ型のdouble型配列確保 for( int i=0; i < n; i++ ) { a[i] = new double[m]; //一つ前で作った要素数nの配列をm個確保 } for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ a[i][j]=j; } } for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ cout<<a[i][j]<<endl; } } for( int i=0; i < n; i++ ) { delete[] a[i]; //deleteで開放。 } delete[] a; //deleteで開放 return 0; } </pre> }} *クラスのオブジェクトの動的確保について ※クラスのオブジェクトの場合、標準入力からのオブジェクトの動的確保はできません。 動的確保ができないので、set関数を使ってnewした後に値を与えます。 **Person.h #html2(){{ <pre class="brush: cpp;"> #include < string > using namespace std; class Person{ private: string name; int age; float height; float weight; int id; //人を識別するためのID static int sum_person; //Personオブジェクトの総数保存変数 public: Person(void); ~Person(void); void setStatus(); //set関数 void selfIntroduction(); }; </pre> }} **Person.cpp #html2(){{ <pre class="brush: cpp;"> #include "Person.h" #include < iostream > int Person::sum_person=0; //static変数 //デフォルトコンストラクタ Person::Person(void){ Person::sum_person++; //総数+1 this->id=sum_person; //現在の総数をIDとして代入 } //デストラクタ Person::~Person(void){ } void Person::setStatus(){ cout<<"ID:"<<this->id<<"のデータを入力します。"<< endl; cout<<"名前を入力:"<<endl; cin >> this->name; cout<<"年齢を入力:"<<endl; cin >> this->age; cout<<"身長を入力:"<<endl; cin >> this->height; cout<<"体重を入力:"<<endl; cin >> this->weight; cout<<"データの入力が完了しました。"<<endl; } void Person::selfIntroduction(){ cout << "私の名前は" << this->name<<"です。"<<endl; cout <<"年齢は"<<this->age<<"歳で、身長は"<<this->height <<"cmで、体重は"<<this->weight << "kgです。" << endl; } </pre> }} **main.cpp #html2(){{ <pre class="brush: cpp;"> #include "Person.h" #include < iostream > using namespace std; int main(){ const int NUM=3; Person *p[NUM]; for(int i=0; i < NUM; i++){ p[i]=new Person();//Person型オブジェクトpをnum個作成 } for(int i=0; i < NUM; i++){ p[i]->setStatus(); } for(int i=0; i < NUM; i++){ p[i]->selfIntroduction(); } return 0; } </pre> }} memo ※static変数は、明示的に初期値を与えなかった場合には、自動的に 0 で初期化される。 ※インスタンスを生成しなくても、静的メンバ変数だけは存在している。 ※静的メンバ変数を宣言した場合、その実体の定義をクラス定義の外側に記述する必要がある。  cpp の"include の下あたりに クラス名::変数名=値;で定義する。 *問題 **問題1 HumanとBoxの2つのクラスを作成しmainでオブジェクトを2つ生成せよ。 HumanとBoxは下記の仕様で作成せよ。 Humanクラス private  性質:string型 name public  操作:putBall   返り値:なし    引数1 :整数型 num(玉を入れる個数)   引数2 :Box型 *b (どのBoxに入れるか)   指定された (Box b) に引数1で指定した(num)個ボールを入れる操作を行う コンストラクタ  引数:string name  引数を使ってnameをセットする。 Boxクラス private  性質:整数型 capacity(容量)    :整数型 ballnum(持っているボールの個数) public  操作:addBall   返り値:なし   引数1:整数型 num   num個持っているボールを持っているボールの個数に加算する。   容量以上のボールはあふれるように処理し、溢れたことを標準出力でユーザに伝える。   :dispBallnum   返り値:なし   引数:なし   現在のボール個数を画面に出力する。 コンストラクタ  引数1 整数型 capacity  引数2 整数型 ballnum  引数を使って箱の容量と入っているボール個数の初期値をセットする。 main  Human(taro,jiro)とBox(b1,b2)のオブジェクトを2つ生成  b1:初期値は容量10,現在のボール数0  b2:初期値は容量20,現在のボール数5  各Boxの現在の個数を標準出力  taroはb1に玉を10個入れる  jiroはb2に玉を15個入れる  各Boxの現在の個数を標準出力  taroはb2に玉を10個入れる  jiroはb1に玉を15個入れる  各Boxの現在の個数を標準出力  生成したオブジェクトを削除  プログラム終了 //#include(highlight) testcounter 合計 &counter(total) 今日 &counter(today) 昨日 &counter(yesterday)
*オブジェクトポインタとは ※こちらも参照 [[オブジェクト]] 通常のポインタと同様、クラスに対してもポインタで扱うことができる。 クラス型のポインタpはobjを指すようになる。 Person obj; Person *p = &obj; ポインタの場合、各変数や関数にアクセスする時は 下の例のように->(アロー演算子)を使用する。 p->age; p->selfIntroduction(); *メモリの動的確保と解放(malloc & free、 new & delete) **new 演算子 C、C++の配列は動的な配列の確保ができない。 new演算子を使うとメモリの動的確保が可能になる。 new,deleteはC++ の演算子なのでincludeの必要はない。 cの<stdlib.h>にあるmalloc と freeでも使用可能 ただし、演算子オーバーロードが使えない、コンストラクタ、デストラクタが呼び出せないため、C++ではnew と deleteを使う。 例: double a[10]; // 静的な確保はOK int n; cin >> n; // キーボードから入力 double b[n]; // NG コンパイルエラーになる  mallocの詳細 形式: #include <stdlib.h>   void *malloc(size_t size); 機能: 大きさsizeのメモリ領域を確保する。 引数: size: 確保したいメモリのバイトサイズ。 返却値: 成功した時:確保したメモリブロックを示すポインタ 失敗した時:NULL 例1:mallocによる動的確保とfreeによる領域解放 #html2(){{ <pre class="brush: cpp;"> #include < iostream > int main(void) { using namespace std; int *ip; /* 割り振られた領域のアドレスを格納するためのint型のポインタipを宣言 */ int n; /* 確保する要素数を入力 */ cout << "要素数を入力してください: " <<endl; cin >> n; ip = (int *)malloc(n * sizeof(int)); /* メモリ領域の確保 */ for (int i=0; i < n; i++){ ip[i] = i; } for (int i=0;i < n; i++) cout<< ip[i] << endl; free(ip); /* 確保したメモリ領域の解放 */ return 0; } </pre> }} 例2:newによる動的確保とdeleteによる領域確保 #html2(){{ <pre class="brush: cpp;"> #include < iostream > int main(void){ using namespace std; int n; cin >> n; int * b = new int[n]; // b を確保 for(int i=0; i < n; i++){ b[i]=i; } for(int i=0; i < n; i++){ cout<< b[i] << endl; } delete[] b; // b を解放 return 0; } </pre> }} *二次元配列の場合の動的確保 通常の二次元配列(b[][])だと動的確保ができないので、ポインタ配列を使って擬似的に作り出します。 以下がソースコードです。 #html2(){{ <pre class="brush: cpp;"> #include < iostream > int main(void){ using namespace std; int n,m; cin >> n; cin >> m; //二次元の時はダブルポインタ(** a)を使用 double ** a = new double*[n]; //n個のポインタ型のdouble型配列確保 for( int i=0; i < n; i++ ) { a[i] = new double[m]; //一つ前で作った要素数nの配列をm個確保 } for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ a[i][j]=j; } } for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ cout<<a[i][j]<<endl; } } for( int i=0; i < n; i++ ) { delete[] a[i]; //deleteで開放。 } delete[] a; //deleteで開放 return 0; } </pre> }} *クラスのオブジェクトの動的確保について ※クラスのオブジェクトの場合、標準入力からのオブジェクトの動的確保はできません。 動的確保ができないので、set関数を使ってnewした後に値を与えます。 **Person.h #html2(){{ <pre class="brush: cpp;"> #include < string > class Person{ private: std::string name; int age; float height; float weight; int id; //人を識別するためのID static int sum_person; //Personオブジェクトの総数保存変数 public: Person(void); ~Person(void); void setStatus(); //set関数 void selfIntroduction(); }; </pre> }} **Person.cpp #html2(){{ <pre class="brush: cpp;"> #include "Person.h" #include < iostream > using namespace std; int Person::sum_person=0; //static変数 //デフォルトコンストラクタ Person::Person(void){ Person::sum_person++; //総数+1 this->id=sum_person; //現在の総数をIDとして代入 } //デストラクタ Person::~Person(void){ } void Person::setStatus(){ cout<<"ID:"<<this->id<<"のデータを入力します。"<< endl; cout<<"名前を入力:"<<endl; cin >> this->name; cout<<"年齢を入力:"<<endl; cin >> this->age; cout<<"身長を入力:"<<endl; cin >> this->height; cout<<"体重を入力:"<<endl; cin >> this->weight; cout<<"データの入力が完了しました。"<<endl; } void Person::selfIntroduction(){ cout << "私の名前は" << this->name<<"です。"<<endl; cout <<"年齢は"<<this->age<<"歳で、身長は"<<this->height <<"cmで、体重は"<<this->weight << "kgです。" << endl; } </pre> }} **main.cpp #html2(){{ <pre class="brush: cpp;"> #include "Person.h" #include < iostream > int main(){ using namespace std; const int NUM=3; Person *p[NUM]; for(int i=0; i < NUM; i++){ p[i]=new Person();//Person型オブジェクトpをnum個作成 } for(int i=0; i < NUM; i++){ p[i]->setStatus(); } for(int i=0; i < NUM; i++){ p[i]->selfIntroduction(); } return 0; } </pre> }} memo ※static変数は、明示的に初期値を与えなかった場合には、自動的に 0 で初期化される。 ※インスタンスを生成しなくても、静的メンバ変数だけは存在している。 ※静的メンバ変数を宣言した場合、その実体の定義をクラス定義の外側に記述する必要がある。  cpp の"include の下あたりに クラス名::変数名=値;で定義する。 *問題 **問題1 HumanとBoxの2つのクラスを作成しmainでオブジェクトを2つ生成せよ。 HumanとBoxは下記の仕様で作成せよ。 Humanクラス private  性質:string型 name public  操作:putBall   返り値:なし    引数1 :整数型 num(玉を入れる個数)   引数2 :Box型 *b (どのBoxに入れるか)   指定された (Box b) に引数1で指定した(num)個ボールを入れる操作を行う コンストラクタ  引数:string name  引数を使ってnameをセットする。 Boxクラス private  性質:整数型 capacity(容量)    :整数型 ballnum(持っているボールの個数) public  操作:addBall   返り値:なし   引数1:整数型 num   num個持っているボールを持っているボールの個数に加算する。   容量以上のボールはあふれるように処理し、溢れたことを標準出力でユーザに伝える。   :dispBallnum   返り値:なし   引数:なし   現在のボール個数を画面に出力する。 コンストラクタ  引数1 整数型 capacity  引数2 整数型 ballnum  引数を使って箱の容量と入っているボール個数の初期値をセットする。 main  Human(taro,jiro)とBox(b1,b2)のオブジェクトを2つ生成  b1:初期値は容量10,現在のボール数0  b2:初期値は容量20,現在のボール数5  各Boxの現在の個数を標準出力  taroはb1に玉を10個入れる  jiroはb2に玉を15個入れる  各Boxの現在の個数を標準出力  taroはb2に玉を10個入れる  jiroはb1に玉を15個入れる  各Boxの現在の個数を標準出力  生成したオブジェクトを削除  プログラム終了 //#include(highlight) testcounter 合計 &counter(total) 今日 &counter(today) 昨日 &counter(yesterday)

表示オプション

横に並べて表示:
変化行の前後のみ表示:
目安箱バナー