オブジェクトポインタとは

※こちらも参照 オブジェクト
通常のポインタと同様、クラスに対してもポインタで扱うことができる。

クラス型のポインタ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による領域解放
#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;

}

例2:newによる動的確保とdeleteによる領域確保

#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;       
}


二次元配列の場合の動的確保

通常の二次元配列(b[][])だと動的確保ができないので、ポインタ配列を使って擬似的に作り出します。
以下がソースコードです。
#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;
}


クラスのオブジェクトの動的確保について

※クラスのオブジェクトの場合、標準入力からのオブジェクトの動的確保はできません。
動的確保ができないので、set関数を使ってnewした後に値を与えます。

Person.h

#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();
};


Person.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;
}

main.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;
}

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の現在の個数を標準出力
 生成したオブジェクトを削除
 プログラム終了



testcounter
合計 -
今日 -
昨日 -