C++中的代码重用-进阶_WUYANGEZRA的博客-程序员秘密

技术标签: C++  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;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Ezra1991/article/details/81458341

智能推荐

IDEA创建Maven项目并配置WEB环境_小唐要努力的博客-程序员秘密_idea配置maven web

创建Maven项目配置WEB环境有两种方式,一种是使用Maven模板,一种不使用。如果使用模板创建,需要勾选从模板创建,然后选择maven包下的webapp模板,注意这里有两个webapp模板,不要选错了,后面的跟着来就可以了,这种方法比较方便。然后我们看看如何不使用模板创建maven项目,并配置好WEB环境。第一步是直接创建maven项目,不勾选从模板创建选项,填写相关项目名,来到主界面。第二步,我们要给新建的项目添加WEB模块,新建的项目是普通的java工程,没有WEB模块。点击

桌面应用使用谷歌浏览器内核CEF_lin49940的博客-程序员秘密_cef浏览器内核

CEF全称Chromium Embedded Framework,是一个基于Google Chromium 的开源项目。C# 有CefSharp, 支持WPF 和 winformPython 有cefpython3, 支持wxPython, PyQt 等很多ptyhon gui 框架。目前自己使用在WPF 和wxPython 上面了, 代码就不贴了, 因为每个不同的版本代码都会有...

杂事_weixin_30951743的博客-程序员秘密

昨天跟一个微信上的中医买了治疗皮肤的药,685,钱和地址给了,不知道什么时候给寄过来,婧婧介绍的,她的妹妹治好了,期待自己也能好。昨天联系上上家公司行政,我的建行卡还没还回来,行政还是说快了,每次都是,不知道什么时候才还,以后不能借,行政居然在休产假,我印象里还是小姑娘,居然都怀孕了,小姑娘好样的。今天给个小姑娘讲了怎么复习数据结构,小姑娘算法考的多,算起来好多学生算法都考的多啊。安排...

App启动白屏和黑屏如何处理?_childhooding的博客-程序员秘密

一、原因: 在应用刚启动和应用未初始化完全之间有一段时间空隙,叫StartingWindow,看起来就像Activity已经启动,只是没填充好数据。所以它是个临时窗口,对应的WindowType是TYPE_APPLICATION_STARTING。目的是告诉用户,系统已经接受到操作,正在响应,在程序初始化完成后实现目的UI,同时移除这个窗口。Window布局的顶层是DecorView,Starti

【已解决】Python 3.8 安装matplotlib,无版本匹配,换清华源即可_Vc_lalala的博客-程序员秘密_python3.8安装matplotlib

【已解决】Python 3.8 安装matplotlib,无版本匹配,换清华源即可,无需改版本!!

数论_逆元_feng_zhiyu的博客-程序员秘密

转自: http://www.cnblogs.com/linyujun/p/5194184.html先来引入求余概念(a + b) % p = (a%p + b%p) %p (对)(a - b) % p = (a%p - b%p) %p (对)(a * b) % p = (a%p * b%p) %p (对)(a / b) % p = (a%p / b%p) %p

随便推点

SQL删除某个时间段的数据_weixin_30802273的博客-程序员秘密

DELETE from dbcp_log_read where time BETWEEN '2017-02-20 00:00:00' AND '2017-03-06 00:00:00'转载于:https://www.cnblogs.com/ouyanxia/p/6510781.html

Java 中如何使用动态数组_开开心心 everyday的博客-程序员秘密

新建 ArrayList对象 ,然后使用add即可例如:ArrayList list = new ArrayList(); for( int i=0;i &lt;10;i++ ) list.Add(i); 参考: https://www.cnblogs.com/qingchunshiguang/p/6103731.html...

vscode 小程序wxml文件代码没有颜色区分(高亮)解决办法_前端步锦的博客-程序员秘密_vscode wxml高亮

打开编辑器wxml文件,右下角,点击如下图部分:在上面的弹框中选择“HTML”语言模式:就可以正常显示了PS:其他语言模式也可以任意切换,就看自己需要什么格式了~...

Effective Objective-C(第37-40条)block在栈上?在堆上?_hherima的博客-程序员秘密_gcd中的block是在堆上还是栈上

OC中多线程编程的核心就是block与gcd。这虽然是两种不同的技术,但他们是一并引入的。block是一种可在C、C++及OC代码中使用的“词法闭包”(lexical closure),它极为有用,借此机制,开发者可将代码像对象一样传递,令其在不同环境(context)下运行。在block的范围内,它可以访问到其中的全部变量。 gcd是一种与block有关的技术,它提供了对线程的抽象,而这种抽象基于“派发队列”(dispatch queue)。开发者可将block排入队列中,有gcd负责处理所有调度

laravel-mongodb操作数组,在指定下标位置插入元素_fadedsun的博客-程序员秘密

laravel使用mongodb请记住不要使用模型,否则就GG了$res = DB::collection('questionnaire')-&gt;where('_id', '5d35797a8c97450e896594b7')-&gt;update( [ '$push' =&gt; [ 'i...

C语言 计算1+1/2!+1/3!+1/4! +…+1/n!的值_奕兴_Victor的博客-程序员秘密

#include&lt;stdio.h&gt;int fun(int n){ int i = 0; int flag = 1; //存返回值 if (0 == n || 1 == n){ return 1; }else{ for (i = 2; i &lt;= n; i++){ flag *= i; } return flag; }}double sum(int n){//求和函数 int i; double sum =

推荐文章

热门文章

相关标签