2018年02月01日
《その270》 クラステンプレートの汎用性
前々回《268》の 演習9-9 では、クラステンプレート SimpleStack<> を利用して、
SimpleStack<char>型のオブジェクトを作りました。
クラステンプレートの汎用性を確認するため、クラステンプレート SimpleStack<> の部分は全く変更せず、これを利用するプログラムの部分だけを入れ替えて
SimpleStack<string>型のオブジェクトを作ってみました。
プログラムの実行結果から、クラステンプレートの汎用性を確認することができました。
以下がプログラムです。
SimpleStack.h
SimpleStackImplementation.h
は、全く変更なしです。
SimpleStackTest.cpp
のみ、string用に変更してあります。
// SimpleStack.h
#ifndef ___Class_SimpleStack
#define ___Class_SimpleStack
// スタッククラステンプレート
template<class Type> class SimpleStack {
int size; // スタック容量
int ptr; // スタックポインタ
Type* stk; // 先頭要素へのポインタ
// コピーコンストラクタの無効化
SimpleStack(const SimpleStack<Type>&);
// 代入演算子の無効化
SimpleStack& operator=(const SimpleStack<Type>&);
public:
class Overflow { }; // Overflow例外
class Empty { }; // Empty例外
// コンストラクタ
explicit SimpleStack(int sz);
// デストラクタ
~SimpleStack();
// push
Type& push(const Type& x);
// pop
Type pop();
// 頂上のデータ
Type& peek();
// スタックの容量
int capacity();
// スタックが満杯
bool is_full();
// スタックが空
bool is_empty();
};
#include "SimpleStackImplementation.h"
#endif
// SimpleStackImplementation.h
#ifndef ___Class_SimpleStackImplementation
#define ___Class_SimpleStackImplementation
// コンストラクタ
template<class Type>
SimpleStack<Type>::SimpleStack(int sz)
: size(sz), ptr(0) {
stk = new Type[size];
}
// デストラクタ
template<class Type>
SimpleStack<Type>::~SimpleStack() {
delete[] stk;
}
// push
template<class Type>
Type& SimpleStack<Type>::push(const Type& x) {
if (ptr >= size)
throw Overflow();
return stk[ptr++] = x;
}
// pop
template<class Type>
Type SimpleStack<Type>::pop() {
if (ptr <= 0)
throw Empty();
return stk[--ptr];
}
// 頂上のデータ
template<class Type>
Type& SimpleStack<Type>::peek() {
if (ptr <= 0)
throw Empty();
int temp = ptr - 1;
return stk[temp];
}
// スタックの容量
template<class Type>
int SimpleStack<Type>::capacity() {
return size;
}
// スタックが満杯
template<class Type>
bool SimpleStack<Type>::is_full() {
return size == ptr;
}
// スタックが空
template<class Type>
bool SimpleStack<Type>::is_empty() {
return ptr == 0;
}
#endif
// SimpleStackTest.cpp
#include <string>
#include <iostream>
#include "SimpleStack.h"
using namespace std;
void push_it(SimpleStack<string>& s, string c) {
try {
s.push(c);
}
catch (const SimpleStack<string>::Overflow&) {
cout << "\a !満杯の<string>スタックに"
"プッシュしようとしました。\n";
}
}
void pop_it(SimpleStack<string>& s) {
try {
string c = s.pop();
cout << ' ' << c << '\n';
}
catch (const SimpleStack<string>::Empty&) {
cout << "\a !空の<string>スタックから"
"ポップしようとしました。\n";
}
}
void pop_all(SimpleStack<string>& s) {
if (s.is_empty()) {
pop_it(s); goto L;
}
while (!s.is_empty()) {
cout << ' ' << s.pop();
}
cout << '\n';
L:;
}
int main() {
int nn;
cout << "スタックの容量 : "; cin >> nn;
SimpleStack<string> s(nn);
cout << "容量 " << s.capacity()
<< " のスタックを準備しました。\n";
while (1) {
int f; string c;
cout << "◆ 1.push 2.pop "
"3.頂上のデータ "
"4.全データをpop 0.終了 : ";
cin >> f;
if (f == 1) {
cout << " 文字列 : "; cin >> c;
push_it(s, c);
}
else if (f == 2)
pop_it(s);
else if (f == 3)
cout << ' ' << s.peek() << '\n';
else if (f == 4) {
pop_all(s);
}
else break;
if (s.is_full()) cout << " ※満\n";
if (s.is_empty()) cout << " ※空\n";
}
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7265020
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック