はじめに
前回の記事から続いてクラスについて説明していきます。
コンストラクタはクラスやオブジェクトをうまく利用するのに便利な機能です。しっかりと扱えるようになりましょう!
コンストラクタについて
コンストラクタはクラスからオブジェクトの生成を行った時に実行される特殊なメンバ関数です。
返り値のデータ型はなく、名前はクラス名と同一の「public」メンバ関数として次のように宣言します。
class クラス名{ 内容 public: クラス名(){ //コンストラクタ 内容 } };
具体的には次のようにしてクラスのメンバ変数の初期化などを行います。
class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } temp(){ //コンストラクタ a = b = 0; } }
もちろんですが、次のようにクラス内でプロトタイプ宣言を行うことも可能です。
class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } temp(); //コンストラクタのプロトタイプ宣言 }; temp::temp(){ a = b = 0; }
引数のあるコンストラクタ
コンストラクタは関数なので引数をとることもできます。
引数のあるコンストラクタは通常の関数と同じように宣言します。
また、デフォルト値のない引数があるコンストラクタのみを宣言した場合(デフォルト引数がなく、オーバーロードに引数なしが含まれていない場合)には次のようにオブジェクトを生成する時に必ず引数を与える必要があります
class クラス名{ 内容 public: クラス名(仮引数){ //引数のあるコンストラクタ 内容 } }; int main(){ クラス名 オブジェクト名(引数); //引数を使ってのオブジェクトの生成 内容 return 0; }
具体的には次のようになります。
#include<iostream> class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } temp(int); //コンストラクタのプロトタイプ宣言 }; temp::temp(int x){ a = x; b = 2*x; } int main(){ temp sample(2); //引数を使ってのオブジェクトの生成 std::cout << sample.sS() << std::endl; return 0; }
ここで再度注意していただきたいことが、オブジェクト生成の際に引数が必ず必要となるのはデフォルト値のない引数があるコンストラクタのみを宣言した場合ということです。
デフォルト引数のあるコンストラクタ
先ほども少しだけ触れましたが、通常の関数と同じくデフォルト引数を与えることができます。
プロトタイプ宣言を行わない場合には関数の宣言の引数に、行う場合にはプロトタイプ宣言の引数に初期値を入力します。
プロトタイプ宣言を行わない場合は具体的に次のようになります。
#include<iostream> class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } temp(int x = 1){ //デフォルト引数のあるコンストラクタ a = x; b = 2*x; } }; int main(){ temp sample1; //デフォルト引数を利用したオブジェクトの生成 std::cout << sample1.sS() << std::endl; temp sample2(2); //引数を利用したオブジェクトの生成 std::cout << sample2.sS() << std::endl; return 0; }
プロトタイプ宣言を行う場合には具体的に次のようになります。
#include<iostream> class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } temp(int x = 1); //デフォルト引数のあるコンストラクタのプロトタイプ宣言 }; temp::temp(int x){ a = x; b = 2*x; } int main(){ temp sample1; //デフォルト引数を利用したオブジェクトの生成 std::cout << sample1.sS() << std::endl; temp sample2(2); //引数を利用したオブジェクトの生成 std::cout << sample2.sS() << std::endl; return 0; }
オーバーロードを行う
コンストラクタは、同一名称で引数のデータ型や数が異なる関数について、オーバーロードを行うことができます。
具体的には次のようになります。
#include<iostream> class temp{ int a,b; //privateメンバ変数 public: int sS(){ //メンバ関数 return a*a+b*b; } //オーバーロード temp(int x){ //引数が1つあるコンストラクタ a = x; b = 2*x; } temp(){ //引数のないコンストラクタ a = b = 1; } }; int main(){ temp sample1(2); //引数のあるオブジェクトの生成 std::cout << sample1.sS() << std::endl; temp sample2; //引数のないオブジェクトの生成 std::cout << sample2.sS() << std::endl; return 0; }
演習問題
演習問題
次の要件を満たすプログラムを作成せよ。
- 次の要件を満たすクラスを作成する
- メンバ変数を二つ宣言
- 二つの引数を取りメンバ変数それぞれに格納するコンストラクタを宣言(デフォルト値をそれぞれ0とする)
- 和の絶対値と差の絶対値を求めるメンバ関数を宣言
- メイン関数で作成したオブジェクトに10,-10を引数としたオブジェクトtemp1と10のみを引数としたオブジェクトtemp2を生成
- temp1およびtemp2の和と差の絶対値を求める関数をそれぞれ標準出力に呼び出す
演習問題解答
いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。
#include<iostream> class abv{ //abvクラスの宣言 int a,b; //private int型 public: abv(int x = 0,int y = 0){ //デフォルト引数のあるコンストラクタ a = x; b = y; } int add(){ //public int型 和の絶対値 if(a+b > 0){ return a+b; }else{ return -a-b; } } int dif(){ //public int型 差の絶対値 if(a-b > 0){ return a-b; }else{ return b-a; } } }; int main(){ abv temp1(10,-10); //abvクラスのtemp1オブジェクトの生成 std::cout << temp1.add() << std::endl; std::cout << temp1.dif() << std::endl; abv temp2(10); //abvクラスのtemp2オブジェクトの生成 std::cout << temp2.add() << std::endl; std::cout << temp2.dif() << std::endl; return 0; }
最後に
かなりさっぱりとした説明でしたが、どうだったでしょう。
わからない点があればコメントなりツイッターなりで解答します。
コメント