速習 CプログラマのためのC++プログラミング入門 サンプルプログラム集

コンピュータを学習する人の学校:パソコンキャンパス、プログラミングキャンパス

ここでは、 The Office Uchida, School of Computerの e-Learningシステム 「速習 CプログラマのためのC++プログラミング入門」のためのサンプルプログラムを紹介しています。

この中に記載されているプログラムをブラウズあるいはカットアンドペーストしてください。

目次に戻る


第6章 テンプレートとSTL(Standard Template Library)

内容
Sample list 6-1 汎用swap関数
Sample list 6-2 int型だけ特別扱い
Sample list 6-3 stringクラスの交換
Sample list 6-4 任意の型の座標を格納できるPointクラス
Sample list 6-5 複数のクラス・型のテンプレート
Sample list 6-6 stringクラス
Sample list 6-7 stringクラスのコンストラクタ
Sample list 6-8 vectorクラス
Sample list 6-9 例外の補足
Sample list 6-10 vectorの操作
Sample list 6-11 アルゴリズム:ソート
Sample list 6-12 さまざまなアルゴリズム
Sample list 6-13 ファイル出力

C++には、型に対して汎用的な関数やクラスを作るテンプレートという文法が用意されています。

Sample list 6-1 汎用swap関数temp_swap.cpp
#include <iostream>
using namespace std;

template <class Type> 
void myswap( Type &a, Type &b )
{
	Type temp = a;

	a = b;
	b = temp;
}

int main()
{
	int    a = 1,   b = 2;
	double x = 1.0, y = 2.0;

	cout << "a=" << a << ",b=" << b << endl;
	myswap( a, b );
	cout << "a=" << a << ",b=" << b << endl;

	cout << "x=" << x << ",y=" << y << endl;
	myswap( x, y );
	cout << "x=" << x << ",y=" << y << endl;

	return 0;
}

本当はswapという関数名を使いたかったのですが、stdネームスペースにswapが定義されているため、myswapという名前にしました。

Sample list 6-1の実行結果(cygwin)

% c++ temp_swap.cpp
% ./a
a=1,b=2
a=2,b=1
x=1,y=2
x=2,y=1

目次に戻る, 先頭に戻る


int型のものだけオーバーロードする

Sample list 6-2 int型だけ特別扱いint_swap.cpp
#include <iostream>
using namespace std;

template <class Type> 
void myswap( Type &a, Type &b )
{
	cout << "Type version is called" << endl;

	Type temp = a;

	a = b;
	b = temp;
}

template<>
void myswap<int>( int &a, int &b )
{
	cout << "int version is called" << endl;

	int temp = a;

	a = b;
	b = temp;
}

int main()
{
	int    a = 1,   b = 2;
	double x = 1.0, y = 2.0;

	cout << "a=" << a << ",b=" << b << endl;
	myswap( a, b );
	cout << "a=" << a << ",b=" << b << endl;

	cout << "x=" << x << ",y=" << y << endl;
	myswap( x, y );
	cout << "x=" << x << ",y=" << y << endl;

	return 0;
}
Sample list 6-2の実行結果(cygwin)

% c++ int_swap.cpp
% ./a
a=1,b=2
int version is called
a=2,b=1
x=1,y=2
Type version is called
x=2,y=1

目次に戻る, 先頭に戻る


一般のクラスも対象になる。

Sample list 6-3 stringクラスの交換temp_swap_class.cpp
#include <iostream>
using namespace std;

template <class Type> 
void myswap( Type &a, Type &b )
{
	Type temp = a;

	a = b;
	b = temp;
}

int main()
{
	string s1 = "one";
	string s2 = "two";

	cout << "s1=" << s1 << ",s2=" << s2 << endl;
	myswap( s1, s2 );
	cout << "s1=" << s1 << ",s2=" << s2 << endl;

	return 0;
}
Sample list 6-3の実行結果(cygwin)

%c++ temp_swap_class.cpp
% ./a
s1=one,s2=two
s1=two,s2=one

目次に戻る, 先頭に戻る


任意の型の座標を格納できるPointクラス

Sample list 6-4 任意の型の座標を格納できるPointクラスtemp_point.cpp
#include<iostream>
using namespace std;

template <class Type>
class Point
{
	Type x, y;

public:
	Point( Type, Type );

	void pr();
};

template <class Type>
Point<Type>::Point( Type ax, Type ay )
{
	this->x = ax;
	this->y = ay;
}

template <class Type>
void Point<Type>::pr()
{
	cout << "(" << this->x << "," << this->y << ")" << endl;
}

int main()
{
	Point<int> pint( 0, 1 );
	Point<double> pdouble( 1.2, 3.4 );
	Point<char> pchar( 'a', 'b' );

	pint.pr();
	pdouble.pr();
	pchar.pr();

	return 0;
}
Sample list 6-4の実行結果(cygwin)

% c++ temp_point.cpp
% ./a
(0,1)
(1.2,3.4)
(a,b)

目次に戻る, 先頭に戻る


複数のクラス・型のテンプレートを作る

Sample list 6-5 複数のクラス・型のテンプレートany_swap.cpp
#include <iostream>
using namespace std;

template <class Type1, class Type2> 
void myswap( Type1 &a, Type2 &b )
{
	long double temp = a;

	a = (Type1)b;
	b = (Type2)temp;
}

int main()
{
	double x = 2.5;
	int y = 5;

	cout << "x=" << x << ", y=" << y << endl;
	myswap( x, y );
	cout << "x=" << x << ", y=" << y << endl;

	return 0;
}
Sample list 6-5の実行結果(cygwin)

% c++ any_swap.cpp
% ./a
x=2.5, y=5
x=5, y=2.5

目次に戻る, 先頭に戻る


stringクラス

Sample list 6-6 stringクラスstr1.cpp
#include<iostream>
using namespace std;

int main()
{
	string s1 = "abcdefg";
	string s2 = "hijklmnopqrstu";

	string st = s1 + s2; // 文字列の連結

	cout << "1:" << st << endl;

	st.insert( 5, "***" );

	cout << "2:" << st << endl;

	st.replace( 5, 3, "---" );

	cout << "3:" << st << endl;

	string s3 = st.substr( 5, 3 );

	cout << "4:" << st << endl;
	cout << "5:" << s3 << endl;

	return 0;
}
Sample list 6-6の実行結果(cygwin)

% c++ str.cpp
% ./a
1:abcdefghijklmnopqrstu
2:abcde***fghijklmnopqrstu
3:abcde---fghijklmnopqrstu
4:abcde---fghijklmnopqrstu
5:---

目次に戻る, 先頭に戻る


stringクラスのコンストラクタ

Sample list 6-7 stringクラスのコンストラクタstr2.cpp
#include<iostream>
using namespace std;

int main()
{
	string s1 = "abcdefg";
	string s2( "hijklmnop" );
	string s3( s2 );

	char str[] = "1234567890";
	string s4( str );

	return 0;
}

目次に戻る, 先頭に戻る


vectorクラス

Sample list 6-8 vectorクラスvector1.cpp
#include<iostream>
#include<vector>
using namespace std;

int main()
{
	const int n=10;

	vector<int> v1;

	for( int k=0; k<n; k++ )
		v1.push_back( k+1 );

	for( int k=0; k<n; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	for( int k=0; k<n; k++ )
		cout << v1.at(k) << ", ";
	cout << endl;

	for( int k=0; k<n+1; k++ ) // エラー;しかし、終了しない
		cout << v1[k] << ", ";
	cout << endl;

	for( int k=0; k<n+1; k++ ) // エラー;Abortする
		cout << v1.at(k) << ", ";
	cout << endl;

	return 0;
}

このプログラムは、異常終了します。

Sample list 6-8の実行結果(cygwin)

% c++ vector1.cpp
% ./a
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Aborted (core dumped)

目次に戻る, 先頭に戻る


例外の補足

Sample list 6-9 例外の補足vector2.cpp
#include<iostream>
#include<vector>
#include<stdexcept>
using namespace std;

int main()
{
	const int n=10;

	vector<int> v1;

	for( int k=0; k<n; k++ )
		v1.push_back( k+1 );

	try
	{
		for( int k=0; k<n+1; k++ ) // エラー;out_of_range例外をスロー
			cout << v1.at(k) << ", ";
		cout << endl;
	}
	catch( out_of_range e ) // out_of_range, runtime_error, exceptionでもキャッチOK
	{
		cout << endl << "例外発生" << endl;
	}
	
	return 0;
}
Sample list 6-9の実行結果(cygwin)

% c++ vector2.cpp
% ./a
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
例外発生

目次に戻る, 先頭に戻る


vectorの操作

Sample list 6-10 vectorの操作vector3.cpp
#include<iostream>
#include<vector>
using namespace std;

int main()
{
	const int n=10;

	vector<int> v1;

	int mz = v1.max_size(); // 確保可能最大数
	cout << "max size=" << mz << endl;

	for( int k=0; k<n; k++ )
		v1.push_back( k+1 ); // 末尾に追加

	for( int k=0; k<n; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	int f = v1.front(); // 先頭要素取得
	int t = v1.back();  // 最後要素取得
	int sz = v1.size(); // 現在の要素数
	
	cout << "front=" << f << endl;
	cout << "back=" << t << endl;
	cout << "size=" << sz << endl;
	
	v1.pop_back(); // 末尾削除
	v1.pop_back(); // 末尾削除
	sz = v1.size(); // 現在の要素数

	cout << "size=" << sz << endl;

	for( int k=0; k<sz; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	return 0;
}
Sample list 6-10の実行結果(cygwin)

% c++ vector3.cpp
% ./a
max size=1073741823
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
front=1
back=10
size=10
size=8
1, 2, 3, 4, 5, 6, 7, 8,

目次に戻る, 先頭に戻る


アルゴリズム:ソート

Sample list 6-11 アルゴリズム:ソートal1.cpp
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
	int k;
	int t[] = { 1, 8, 6, 3, 9, -2, 0, 5, };
	const int n = sizeof t / sizeof t[0];

	vector<int> v1;

	for( k = 0 ; k < n ; k++ )
		v1.push_back( t[k] );

	int sz = v1.size();

	for( k = 0 ; k < sz ; k++ )
		cout << v1.at( k ) << " ";
	cout << endl;

	sort( v1.begin(), v1.end() );

	for( k = 0 ; k < sz ; k++ )
		cout << v1.at( k ) << " ";
	cout << endl;

	return 0;
}
Sample list 6-11の実行結果(cygwin)

% c++ al1.cpp
% ./a
1 8 6 3 9 -2 0 5
-2 0 1 3 5 6 8 9

目次に戻る, 先頭に戻る


さまざまなアルゴリズム

Sample list 6-12 さまざまなアルゴリズムal2.cpp
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
	const int n=10;
	vector<int> v1;

	for( int k=0; k<n; k++ )
		v1.push_back( k+1 ); // 末尾に追加

	int sz = v1.size(); // 
	cout << "size=" << sz << endl;

	for( int k=0; k<sz; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	reverse( v1.begin(), v1.end() );

	for( int k=0; k<sz; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	random_shuffle( v1.begin(), v1.end() );

	for( int k=0; k<sz; k++ )
		cout << v1[k] << ", ";
	cout << endl;

	return 0;
}
Sample list 6-12の実行結果(cygwin)

% c++ al2.cpp
% ./a
size=10
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
9, 10, 6, 4, 3, 5, 1, 2, 8, 7,

目次に戻る, 先頭に戻る


ファイル操作

Sample list 6-13 ファイル出力f.cpp
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
	ofstream ofs( "output.txt" );
	if( ofs == NULL )
	{
		cout << "output.txtを作成できません。" << endl;
		exit( 1 );
	}

	ofs << "おはよう" << endl;
	ofs << "こんにちは" << endl;
	ofs << "こんばんは" << endl;

	ofs.close();

	return 0;
}

目次に戻る, 先頭に戻る


Copyright (c) 2006 Satoshi Uchida, The Office Uchida, School of Computer