C++ 模板使用

模板是解决重用的一种方式,"模板" 顾名思义,一个框框,框架不会轻易变动,但其中的内容可以随意填写。



以一个栈的定义为例:


class stack
{
private:
    enum {ssize = 100};
    int m_stack[ssize];
	int m_top;
public:
    stack() : m_top(0) {m_stack[m_top] = 0;}
	void push(int i)
	{    if (m_top < ssize) {m_stack[m_top++] = i;};  }
	
    int pop()
	{    return stack[m_top > 0 ? --m_top : m_top];  }
}



这个栈最多可以被叫做 int_stack,它只能支持int 类型, 但对与 double 或其他复合类型它就无法满足了。这里的代码也无法被重用。

这时候使用模板就可以很好的解决这个问题。


模板的定义和使用



模板的定义很简单, 使用关键字 template


template <class T>
class stack
{
private:
    enum {ssize = 100};
    T m_stack[ssize];
	int m_top;
public:
    stack() : m_top(0) {m_stack[m_top] = 0;}
	void push(T i)
	{    if (m_top < ssize) {m_stack[m_top++] = i;};  }
	
    T pop()
	{    return stack[m_top > 0 ? --m_top : m_top];  }
}



这个类中把int 改为了 T 类型, 这样stack的框框就确定下来了,但其中的内容是可以随意变化的。可以使用double 当然也可以使用复合类型或者是类。

使用 模板类, 模板类被很好的重用了。


#include "stack_t.h"


void main()
{
    stack<int> istack;
	stack<double> dstack;

	int i = 0;
	double d = 0;

	for (i = 0; i < 10; i++)
	{
		istack.push(i*i);
	}

	for (i = 0; i < 10; i++)
	{
		d = i * 0.01;
		dstack.push(d);
	}

	for (i = 0; i < 10; i++)
	{
		cout << istack.pop() << "    ";
	}
	cout << endl << endl;

	for (i = 0; i < 10; i++)
	{
		cout << dstack.pop() << "    ";
	}
	cout << endl;

	cin >> i;
}



当然模板类中也可以不使用内联函数, 但模板类的声明和实现一定要放在一起,都放在头文件中,否则连接时会出现错误。原因是 由template <...> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知.


#include <iostream>

using namespace std;

#ifndef _STACK_H_
#define _STACK_H_

template <class T>
class stack
{
private:
    enum {ssize = 100};
    T m_stack[ssize];
	int m_top;

public:
    stack() : m_top(0) {m_stack[m_top] = 0;}
	void push(T t);
    T pop();
};

template <class T>
void stack<T>::push(T t)
{
	if (m_top < ssize) {m_stack[m_top++] = t;};  
}

template <class T>
T stack<T>::pop()
{    
	return m_stack[m_top > 0 ? --m_top : m_top]; 
}

#endif




使用模板时内存的释放


一个小小的例子,这个例子可以直接复制到程序中,来节省开发的时间。从例子中也可以看出, 模板类,或者是容器类他们对于对象类型并不负责内存的释放。

内存的释放还是由运行类自己进行的。

#include <iostream>
#include <vector>

using namespace std;

class Tester
{
private:
	int m_id;

public:
	Tester(int id): m_id(id){cout << "Construct a Tester: << "<< m_id << endl;}
	~Tester(){cout << "Destruct a Tester: "<< m_id << endl;}

	void run() {cout << "I am Tester: "<< m_id << endl;};
};


void main()
{
	vector<Tester*> vec;
	int i = 0;

    vec.push_back(new Tester(1));
    vec.push_back(new Tester(2));
    vec.push_back(new Tester(3));
    vec.push_back(new Tester(4));
    vec.push_back(new Tester(5));

	for (vector<Tester*>::iterator it = vec.begin(); it != vec.end(); it ++)   
    if (NULL != *it)   
    {  
        (*it)->run();  
    }

	for (vector<Tester *>::iterator it = vec.begin(); it != vec.end(); it ++)   
    if (NULL != *it)   
    {  
        delete *it;   
        *it = NULL;  
    }
    vec.clear();  

	cin >> i;
}


模板的继承:



模板类与我们普通的类一样支持继承。这里保留一个小例子,以后开发过程中可以直接扩展使用。这里使用的基类就是上面的栈的例子,这里从基类中派生出一个简单的子类,子类中增加了一个统计个数的功能。


stack_t.h

#include <iostream>

using namespace std;

#ifndef _STACK_H_
#define _STACK_H_

template <class T>
class stack
{
protected:
    enum {ssize = 100};
    T m_stack[ssize];
	int m_top;

public:
    stack() : m_top(0) {m_stack[m_top] = 0;}
	void push(T t);
    T pop();
};

template <class T>
void stack<T>::push(T t)
{
	if (m_top < ssize) {m_stack[m_top++] = t;};  
}

template <class T>
T stack<T>::pop()
{    
	return m_stack[m_top > 0 ? --m_top : m_top]; 
}

#endif


stack_static.h

#include <iostream>
#include "stack_t.h"

using namespace std;

#ifndef _STACK_STATIC_H_
#define _STACK_STATIC_H_

template <class T>
class stack_static : public stack<T>
{
public:
	stack_static(){};

	int count(){return m_top;};
};

#endif


main.cpp


#include "stack_static.h"

void main()
{
    stack_static<int> istack;
	stack_static<double> dstack;

	int i = 0;
	double d = 0;

	for (i = 0; i < 10; i++)
	{
		istack.push(i*i);
	}

	for (i = 0; i < 10; i++)
	{
		d = i * 0.01;
		dstack.push(d);
	}

	cout << "===================================" << endl;
	cout << "Total count: " << dstack.count() << endl;
	cout << "===================================" << endl;

	for (i = 0; i < 10; i++)
	{
		cout << istack.pop() << "    ";
	}
	cout << endl << endl;

	for (i = 0; i < 10; i++)
	{
		cout << dstack.pop() << "    ";
	}
	cout << endl;

	cin >> i;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值