オブジェクト指向プログラミングPart2 コンストラクタとデストラクタ MQL5

[← オブジェクト指向プログラミングPart1](https://qiita.com/aisaki180507/items/d343b1ad46c8d3807ec2)

##コンストラクタとデストラクタ
　__コンストラクタ__とはオブジェクトが生成されたときに1度だけ実行されるメソッドで、__デストラクタ__はオブジェクトが消去されたときに実行されるメソッドです。前回作成したクラスにコンストラクタとデストラクタを書き加えて、その動作を確認していきます。

||実行されるタイミング|
|:-:|:--|
|コンストラクタ|オブジェクト生成時|
|デストラクタ|オブジェクト消去時|

###コンストラクタ、デストラクタの書き方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/7f309224-7dc4-4573-fa5a-e369c62bc9cd.png)

実際にコードを書いてみると

```.c
class CRen{
private: 
   int AI;

public: 
   int get_AI() { return AI; };
   void set_AI(int ai) { AI = ai; };
   
   CRen(){ Print("コンストラクタ"); } // コンストラクタ

   ~CRen(){ Print("デストラクタ"); }  // デストラクタ

};

int OnInit()
  {
   CRen ren; // オブジェクト生成
   
   ren.set_AI( 1234 );
   Print( ren.get_AI() );
   
   return(INIT_SUCCEEDED);
  }
```
このプログラムを実行すると↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/12363ccb-68f4-63e5-ceb5-9cddaf46a87f.png)
コンストラクタとデストラクタが動作の最初と最後に実行されていることがわかります。

今度は__OnInit関数__ではなく__OnTick関数__でクラスを呼び出してみます。

```.cpp
class CRen{
private: 
   int AI;

public: 
   int get_AI() { return AI; };
   void set_AI(int ai) { AI = ai; };
   
   CRen(){ Print("コンストラクタ"); } // コンストラクタ
   ~CRen(){ Print("デストラクタ"); }  // デストラクタ
};

int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
   CRen ren; // オブジェクト生成
   
   ren.set_AI( 1234 );
   Print( ren.get_AI() );
   
  }
```
このプログラムを実行すると↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/2981b178-c9a7-6da3-550e-0b21d4630fd1.png)
　OnTick関数は1ティックごとに実行される関数なのでオブジェクト生成/消去も1ティックごとに起こります。そのため1ティックごとにクラスのコンストラクタとデストラクタが実行されることになります。

##メソッドの宣言と定義付けを分けて書く
　メソッドの宣言とと定義を分けて書くことも可能です。クラス内部のメソッドをたくさん作りたい。もしくはメソッドの内容が長くなるときは、メソッドの宣言とと定義を分けて書くとコードが見やすくなったりします。
###書き方
　クラス内部のメソッド宣言で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/ce47d077-8afd-ceb2-8159-b70a3cdac274.png)
　クラスの外側で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/da9c1dbb-946e-abfb-9061-25762df417b5.png)


実際にコードを書いてみると

```.cpp
class CRen{
private: 
   int AI;

public:    
   int get_price(); // メソッドの宣言
   
};

// メソッドの定義付け
int CRen::get_price(void)
{
   AI = 100 + 20;
   
   return AI;
}

int OnInit()
  {
   CRen ren; // オブジェクト生成
   
   Print( ren.get_price() );
   
   return(INIT_SUCCEEDED);
  }

```
このプログラムを実行すると↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/11b509e9-c0ef-9d36-2540-07b1d0fcdda1.png)

###コンストラクタとデストラクタもクラスの外部で定義付けしてみる
コンストラクタとデストラクタの場合はメソッドの定義で型をつける必要がありません。そのほかに書き方に違いはありません。

```.cpp
class CRen{
private: 
   int    AI;
   double SA;

public: 
   int get_AI() { return AI; };
   void set_AI(int ai) { AI = ai; };
   
   CRen();   // コンストラクタ
   ~CRen();  // デストラクタ
};

CRen::CRen(void)
{
   SA = iClose(_Symbol,PERIOD_CURRENT,0);
   Print("コンストラクタ 現在の価格は ",SA);
}

CRen::~CRen(void)
{
   Print("デストラクタ SAの値は ",SA," AIの値は ",AI);
}


int OnInit()
  {
   CRen ren; // オブジェクト生成
   
   ren.set_AI( 1234 );
   Print( ren.get_AI() );
   
   return(INIT_SUCCEEDED);
  }
```
このプログラムを実行すると↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/5156b386-9dc5-6c34-e9be-7a8c99dca798.png)
***
続きを読むときはこちら
[オブジェクト指向プログラミングPart3 →](https://qiita.com/aisaki180507/items/6d6864eba2249f10933b)