C++中的代码重用-进阶

C++中的代码重用

  1. 类模板

可以定义专门用于存储double值或string对象的Stack类,除了保存的对象类型不同外,这两种Stack类的代码是相同的。 然而,与其编写新的类声明,不如编写一个泛型(即独立于类型的)栈,然后将具体的类型作为参数传递给这个类。

  1. 定义模板类

和模板函数一样,模板类以下面这样的代码开头:

template <class Type>

关键字template告诉编译器,将要定义一个模板。 尖括号中的内容相当于函数的参数列表。 可以把关键字class看作是变量的类型名,该变量接受类型作为其值,把Type看作是该变量的名称。

//stacktp.h -- 栈模板
#ifndef STACKTP_H_
#define STACKTP_H_
template<class Type>
class Stack
{
private:
	enum { MAX = 10 };
	Type items[MAX];
	int top;
public:
	Stack();
	bool isempty();
	bool isfull();
	bool push(const Type & item);
	bool pop(Type & item);
};
template<class Type>
Stack<Type>::Stack()
{
	top = 0;
}
template<class Type>
bool Stack<Type>::isempty()
{
	return top == 0;
}
template<class Type>
bool Stack<Type>::isfull()
{
	return top == MAX;
}
template<class Type>
bool Stack<Type>::push(const Type & item)
{
	if (top < MAX)
	{
		items[top++] == item;
		return true;
	}
	else
		return false;
}
template<class Type>
bool Stack<Type>::pop(Type & item)
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}
#endif // !STACKTP_H_
  1. 使用模板类

仅在程序包含模板并不能生成模板类,而必须请求实例化。 为此,需要声明一个类型为模板类的对象,方法是使用所需的具体类型替代泛型名。 例如,下面的代码创建两个栈,一个用于存储int,另一个用于存储string对象:

Stack<int> kernels;      

Stack<string> colonels;

看到上述声明后,编译器将按Stack<Type>模板来生成两个独立的类声明和两组独立的类方法。

泛型标识符——例如这里的Type——成为类型参数,这意味着它们类似于变量,但赋给它们的不能是数字,而只能说类型。

注意,必须显示地提供所需的类型,这与常规的函数模板是不同的,因为编译器可以根据函数的参数类型来确定要生成哪种函数。

//stacktp.h -- 栈模板
#ifndef STACKTP_H_
#define STACKTP_H_
template<class Type>
class Stack
{
private:
	enum { MAX = 10 };
	Type items[MAX];
	int top;
public:
	Stack();
	bool isempty();
	bool isfull();
	bool push(const Type & item);
	bool pop(Type & item);
};
template<class Type>
Stack<Type>::Stack()
{
	top = 0;
}
template<class Type>
bool Stack<Type>::isempty()
{
	return top == 0;
}
template<class Type>
bool Stack<Type>::isfull()
{
	return top == MAX;
}
template<class Type>
bool Stack<Type>::push(const Type & item)
{
	if (top < MAX)
	{
		items[top++] == item;
		return true;
	}
	else
		return false;
}
template<class Type>
bool Stack<Type>::pop(Type & item)
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}
#endif // !STACKTP_H_
//stacktem.cpp -- 测试template stack类
#include<iostream>
#include<string>
#include<cctype>
#include"stacktp.h"
using std::cin;
using std::cout;
int main()
{
	Stack<std::string>st;        //创建一个空栈
	char ch;
	std::string po;
	cout << "Please enter A to add a purchase order,\n"
		<< "P to process a PO, or Q to quit.\n";
	while (cin >> ch && std::toupper(ch) != 'Q')
	{
		while (cin.get() != '\n')
			continue;
		if (!std::isalpha(ch))
		{
			cout << '\a';
			continue;
		}
		switch (ch)
		{
		case'A':
		case'a':
			cout << "Enter a PO number to add: ";
			cin >> po;
			if (st.isfull())
				cout << "stack already full\n";
			else
				st.push(po);
			break;
		case 'P':
		case 'p':
			if (st.isempty())
				cout << "stack alreay empty\n";
			else
			{
				st.pop(po);
				cout << "PO #"<<po<< " popped\n";
				break;
			}
		}
		cout << "Please enter A to add a purchase order,\n"
			<< "p to process a PO, or Q to quit.\n";
	}
	cout << "Bye.\n";
	system("pause");
	return 0;
}
  1. 深入探讨模板类

下列程序重新定义了Stack<Type>类,使Stack构造函数能接受一个可选大小的参数。 这涉及到在内部使用动态数组。 因此,Stack类需要包含一个析构函数、一个复制构造函数和一个赋值运算符。

//stacktp1.h -- 栈模板
#ifndef STACKTP_H_
#define STACKTP_H_
template<class Type>
class Stack
{
private:
	enum { SIZE = 10 };         //默认大小
	int stacksize;
	Type *items;
	int top;
public:
	explicit Stack(int ss=SIZE);
	Stack(const Stack & st);
	~Stack() { delete[]items; }
	bool isempty() { return top == 0; }
	bool isfull() { return top == stacksize; }
	bool push(const Type & item);
	bool pop(Type & item);
	Stack & operator=(const Stack & st);
};
template<class Type>
Stack<Type>::Stack(int ss):stacksize(ss),top(0)
{
	items = new Type[stacksize];
}
template<class Type>
Stack<Type>::Stack(const Stack & st)
{
	stacksize = st.stacksize;
	top = st.top;
	items = new Type[stacksize];
	for (int i = 0; i < top; i++)
		items[i] = st.items[i];
}
template<class Type>
bool Stack<Type>::push(const Type & item)
{
	if (top < stacksize)
	{
		items[top++] == item;
		return true;
	}
	else
		return false;
}
template<class Type>
bool Stack<Type>::pop(Type & item)
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}
template<class Type>
Stack<Type> & Stack<Type>::operator=(const Stack<Type> & st)
{
	if (this == &st)
		return *this;
	delete[]items;
	stacksize = st.stacksize;
	top = st.top;
	items = new Type[stacksize];
	for (int i = 0; i < top; i++)
		items[i] = st.item[i];
	return *this;
}
#endif // !STACKTP_H_
//stkoptr1.cpp -- 测试指针栈
#include<iostream>
#include<cstdlib>
#include<ctime>
#include"stacktp1.h"
const int Num = 10;
int main()
{
	std::srand(std::time(0));
	std::cout << "Please enter stack size: ";
	int stacksize;
	std::cin >> stacksize;
	//创建一个大小为stacksize的空栈
	Stack<const char *>st(stacksize);
	//入栈
	const char * in[Num] = {
		"1: Hank Gilgamesh", "2: Kiki Ishtar",
		"3: Betty Rocker","4: Ian Flagranti",
		"5: Wolfgang Kibble", "6: Portia Koop",
		"7: Joy Almodo", "8: Xaverie Paprika",
		"9: Juan Moore","10: Misha Mache"
	};
	//出栈
	const char *out[Num];
	int processed = 0;
	int nextin = 0;
	while (processed < Num)
	{
		if (st.isempty())
			st.push(in[nextin++]);
		else if (st.isfull())
			st.pop(out[processed++]);
		else if (std::rand() % 2 && nextin < Num)
			st.push(in[nextin++]);
		else
			st.pop(out[processed++]);
	}
	for (int i = 0; i < Num; i++)
		std::cout << out[i] << std::endl;
	std::cout << "Bye\n";
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值