投稿日時: 2014/06/03
S Nakagawa
表示方式変更のため再掲(2014/01/08 OpenFOAM学習者向け C++プログラミング基礎 - クラス、テンプレートクラス)
OpenFOAM 学習者向けのC++プログラミング基礎 学習資料を作成しました。興味ある方は、ご覧ください。コンパイルして、試してください。
OpenFOAM 学習者向けのC++プログラミング基礎 学習資料を作成しました。興味ある方は、ご覧ください。コンパイルして、試してください。
ご意見、ご感想、質問など、大歓迎です。掲示板に返信してください。
例題が陳腐です。良いアイデアがあれば、ぜひ、教えて下さい。
例題が陳腐です。良いアイデアがあれば、ぜひ、教えて下さい。
----
今回の目的:
クラス の基本について学ぶ。
テンプレート クラス の基本について学ぶ。
基本方針:
main はできるだけシンプルにしていく。
ごく基本的なプログラム例を CODE 1 に示す。
このプログラムでは,キーボードから整数を入力し,その値の2倍を画面に表示する。
CODE 1
#include <iostream>
int main()
{
int n;
std::cout << "整数を入力してください。" << std::endl;
std::cin >> n;
std::cout << "整数 " << n << " の2倍は " << n + n << " です。" << std::endl;
return 0;
}
整数(int)型を発展させて,その値を2倍にする機能のある整数型を作り出すとする。
この機能をクラスとして実装する。クラス名を extendedInt とする。
CODE 2
#include <iostream>
// クラスの定義 スタート
class extendedInt
{
int n_;
public:
int makeDouble(const int& n)
{
return n + n ;
};
};
// クラスの定義 ここまで
int main()
{
int n;
extendedInt extInt;
std::cout << "整数を入力してください。" << std::endl;
std::cin >> n;
std::cout << "整数 " << n << " の2倍は " << extInt.makeDouble(n) << " です。" << std::endl;
return 0;
}
クラスに整数を受け取るコンストラクタを作成する。
画面表示部分もクラスに任せることにする。
CODE 3
#include <iostream>
class extendedInt
{
int n_;
public:
// constructor
extendedInt(const int& n )
{
n_ = n;
};
int makeDouble(const int& n)
{
return n + n;
};
bool calcAndDisplay()
{
std::cout << "整数 " << n_ << " の2倍は " << makeDouble(n_) << " です。" << std::endl;
};
};
int main()
{
int n;
std::cout << "整数を入力してください。" << std::endl;
std::cin >> n;
extendedInt extInt(n);
extInt.calcAndDisplay();
return 0;
}
整数を与える部分もクラスに任せてみる。
CODE 4
#include <iostream>
class extendedInt
{
int n_;
public:
int makeDouble(const int& n)
{
return n + n;
};
bool calcAndDisplay()
{
std::cout << "整数 " << n_ << " の2倍は " << makeDouble(n_) << " です。" << std::endl;
};
bool read()
{
std::cout << "整数を入力してください。" << std::endl;
std::cin >> n_;
};
};
int main()
{
extendedInt extInt;
extInt.read();
extInt.calcAndDisplay();
return 0;
}
整数と同じようなものを、実数でも実現したいとする。
単純に考えると、整数用と実数用の2つのクラスを作るかも。
CODE 5
#include <iostream>
// 整数専用クラス
class extendedInt
{
int n_;
public:
int makeDouble(const int& n)
{
return n + n;
};
bool calcAndDisplay()
{
std::cout << "整数 " << n_ << " の2倍は " << makeDouble(n_) << " です。" << std::endl;
};
bool read()
{
std::cout << "整数を入力してください。" << std::endl;
std::cin >> n_;
};
};
// 実数専用クラス
class extendedFloat
{
float f_;
public:
float makeDouble(const float& f)
{
return f + f;
};
bool calcAndDisplay()
{
std::cout << "実数 " << f_ << " の2倍は " << makeDouble(f_) << " です。" << std::endl;
};
bool read()
{
std::cout << "実数を入力してください。" << std::endl;
std::cin >> f_;
};
};
int main()
{
extendedInt extInt;
extInt.read();
extInt.calcAndDisplay();
extendedFloat extFlt;
extFlt.read();
extFlt.calcAndDisplay();
return 0;
}
ほとんど同じことを書いたクラスが2つ。内部に持つ型が異なるだけ。
まとめられないの?templateを使ってまとめましょう。
先ほどの2つのクラスで,int または float だったところを,Type と名前をつけたテンプレートクラスで宣言します。クラスの定義内で,Type となっている部分は,mainから呼び出す際に定めたクラスとなります。
先ほどの2つのクラスで,int または float だったところを,Type と名前をつけたテンプレートクラスで宣言します。クラスの定義内で,Type となっている部分は,mainから呼び出す際に定めたクラスとなります。
CODE 6
#include <iostream>
#include <string>
template<class Type>
class extendedType
{
Type x_;
std::string type_;
public:
extendedType(const std::string& type)
{
type_=type;
}
Type makeDouble(const Type& x)
{
return x + x;
};
bool calcAndDisplay()
{
std::cout << type_ << x_ << " の2倍は " << makeDouble(x_) << " です。" << std::endl;
};
bool read()
{
std::cout << type_ << " を入力してください。" << std::endl;
std::cin >> x_;
};
};
int main()
{
extendedType<int> extInt("整数");
extInt.read();
extInt.calcAndDisplay();
extendedType<float> extFlt("実数");
extFlt.read();
extFlt.calcAndDisplay();
return 0;
}
コンストラクタを作成しました。クラスからオブジェクト(インスタンス)を作る時に、型の名前を渡すようにしました。
mainでの宣言部分に注意してください。宣言時に、クラス側のtemplateが決定されます。
これで、色々な型に対応できます。
文字列型にも。ただし、演算子+が使える必要があります。
CODE 7
#include <iostream>
#include <string>
template<class Type>
class extendedType
{
private:
Type x_;
std::string type_;
public:
extendedType(const std::string& type)
{
type_=type;
}
bool calcAndDisplay()
{
std::cout << type_ << x_ << " の2倍は " << makeDouble(x_) << " です。" << std::endl;
};
bool read()
{
std::cout << type_ << " を入力してください。" << std::endl;
std::cin >> x_;
};
private:
Type makeDouble(const Type& x)
{
return x + x;
};
};
int main()
{
extendedType<int> extInt("整数");
extInt.read();
extInt.calcAndDisplay();
extendedType<float> extFlt("実数");
extFlt.read();
extFlt.calcAndDisplay();
extendedType<std::string> extStr("文字列");
extStr.read();
extStr.calcAndDisplay();
return 0;
}