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

オブジェクトポインタ,newとdelete - (2012/11/12 (月) 18:20:10) の1つ前との変更点

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

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

*オブジェクトポインタとは 通常のポインタと同様、クラスに対してもポインタで扱うことができる。 クラス型のポインタ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: void Person(void); 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 << "私の名前は" << 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[NUM]=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 の下あたりに クラス名::変数名=値;で定義する。 #include(highlight)
*オブジェクトポインタとは 通常のポインタと同様、クラスに対してもポインタで扱うことができる。 クラス型のポインタ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 << "私の名前は" << 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[NUM]=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 の下あたりに クラス名::変数名=値;で定義する。 #include(highlight)

表示オプション

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