02c++模板部分讲解

1理解函数模板

#include<iostream>
using namespace std;

//函数模板
template<typename T> //定义一个模板参数列表
//模板类型参数 typename/class
bool compare(T a, T b)
{
	cout << "template compare: " << endl;
	return a > b;
}

template<>
bool compare(const char* a, const char* b)
{
	cout << "compare(char*)";
	return strcmp(a, b) > 0;
}

//非模板函数
bool compare(const char* a, const char* b)
{
	cout << "normal compare: " << endl;
	return strcmp(a, b) > 0;
}
/*函数调用点,编译器用用户指定的类型,从原来的模板实例化一份函数代码出来*/
int main()
{
	compare<int>(10, 20);
	compare(20, 30); //推导出来是整形 模板实参法推演

	//compare(30, 4.5);b报错,找不到
	compare<int>(30, 3.4); //这样子可以但是被会警告
	//对于某些类型来说,依赖编译器默认实例化的模板代码,代码处理逻辑是有错误的
	compare("aaa", "bbb"); //不能a>b来处理
	//模板的特例化,不是编译器提供的,而是用户提供的实例化
	return 0;
}
//份文件的时候 直接告诉编译器模板指定类型的模板实例化
template bool compare<int>(int, int);
template bool compare<double>(double, double);

2、理解类模板

#include<iostream>
using namespace std;


template<typename T, const int SIZE>
void sort(T* arr)
{
	for (int i = 0; i < SIZE - 1; i++)
	{
		for (int j = 0; j < SIZE - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
//类模板
int main()
{
	int arr[] = { 12,2,2,2,2,2 };
	const int size = sizeof(arr) / sizeof(arr[0]);
	sort<int, size>(arr);
	for (int val : arr)
	{
		cout << val << " ";
	}
	cout << endl;
}

#include<iostream>
using namespace std;
#include<time.h>
template<typename T> //模板+参数列表 = 类名称
class SeqStack
{
public:
	//构造函数和析构函数不要加模板类型参数列表
	SeqStack(int size = 10)
		:_stack(new T[size]),
		_top(0),
		_size(size)
	{}
	~SeqStack()
	{
		delete[]_stack;
		_stack = nullptr;
	}
	SeqStack<T>(const SeqStack<T>& stack)
		:_top(stack._top),
		_size(stack._size)
	{
		_stack = new T[_size];
		//不要用memcopy进行拷贝
		for (int i = 0; i < _top; i++)
		{
			_stack[i] = stack._stack[i];
		}
	}
	SeqStack<T>& operator = (const SeqStack<T>& stack)
	{

		if (this == &stack)return *this;
		delete[] _stack;
		_top = stack._top;
		_size = stack._size;
		_stack = new T[_size];
		//不要用memcopy进行拷贝
		for (int i = 0; i < _top; i++)
		{
			_stack[i] = stack._stack[i];
		}
		return *this;
	}

	void push(const T& val)
	{
		if (full())expand();
		_stack[_top++] = val;
	}
	void pop()
	{
		if (empty())
		{
			return;
		}
		--_top;
	}
	T top() const
	{
		if ((empty()))throw "stack is empty()"; //抛出异常结束
		return _stack[_top - 1];
	}
	bool full()const
	{
		return _top == _size;
	}
	bool empty()const
	{
		return _top == 0;
	}
private:
	T* _stack;
	int _top;
	int _size;
	//顺序栈底层数
	void expand()
	{
		T* ptmp = new T[_size * 2];
		for (int i = 0; i < _top; i++)
		{
			ptmp[i] = _stack[i];
		}
		delete[]_stack;
		_stack = ptmp;
		ptmp = nullptr;
		_size *= 2;
	}
};
int main()
{
	SeqStack<int>stack(4);
	for (int i = 0; i < 20; i++)
	{
		stack.push(rand() % 100);
	}
	while (!stack.empty())
	{
		cout << stack.top() << " ";
		stack.pop();
	}

	cout << endl;
	SeqStack<int>stack1(2);
	stack1.push(1);
	stack1.push(2);
	stack1.push(3);
	stack1.push(4);
	stack1.pop();
	cout << stack1.top();

	return 0;
}

3、SLT实现Vector类

#include<iostream>
using namespace std;

template<class T>
class Vector
{
public:
	Vector(int size = 10)
	{
		_first = new T[size];
		_last = _first;
		_end = _first + size;
	}

	~Vector()
	{
		delete[]_first;
		_first = _last = _end = nullptr;
	}

	Vector(const Vector<T>& rhs)
	{
		int size = rhs._end - rhs._first;
		_first = new T[size]; //空间大小
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			_first[i] = rhs._first[i];
		}
		_last = _first + len;
		_end = _first + size;
	}
	Vector<T>& operator=(const Vector<T>& rhs) //拷贝构造
	{
		if (this == &rhs)return *this;
		delete[] _first;
		int size = rhs._end - rhs._first;
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			_first[i] = rhs._first[i];
		}
		_last = _first + len;
		_end = _first + size;
		return *this;
	}

	void push_back(const T& val)
	{
		if (full())
		{
			expand();
		}
		*_last = val;
		_last++;
	}

	void pop_back()
	{
		if (empty())
		{
			return;
		}
		--_last;
	}
	T back()const //返回容器末尾的元素值
	{
		return *(_last - 1);
	}

	bool full()const { return _last == _end; }
	bool empty()const { return _first == _last; }
	int size()const { return _last - _first; }

private:

	void expand()
	{
		int _size = _end - _first;
		T* tmp = new T[_size * 2];
		for (int i = 0; i < _size; i++)
		{
			tmp[i] = _first[i];
		}
		delete[]_first;
		_first = tmp;
		_last = _first + _size;
		_size *= 2;
		_end = _first + _size;
	}
	T* _first; //指向数组的起始的位置
	T* _last; //指向数组有效元素的后继位置
	T* _end; //指向数组空间的后继位置

};
//容器空间分配器
class Test
{
public:
	Test() { cout << "test()" << endl; }
	~Test() { cout << "~test()" << endl; }
};

int main()
{/*
	Vector<int>vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100);
	}
	while (!vec.empty())
	{
		cout << vec.back() << " ";
		vec.pop_back();
	}
	cout << endl;
	vec.push_back(10);
	cout << vec.back() << endl;
	cout << endl;*/
	Vector<Test>vec;
	return 0;
}

6、容器空间配置

#include<iostream>
using namespace std;



/*
template <class _Ty,
	class _Alloc = allocator<_Ty>>
	class Vector
	容器的空间配置器allocator做四件事情 内存开辟 内存释放 对象构造 对象析构
*/

//定义容器的空间配置器,和c++标准库的allocator实现一样
template<typename T>
class Allocator
{
public:
	T* allocate(size_t size) //负责内存开辟
	{
		return (T*)malloc(sizeof(T) * size);

	}

	void deallocate(void* p) //负责内存释放
	{
		free(p);
	}

	void construct(T* p, const T& val) //负责对象构造
	{
		new (p) T(val);//定位new
	}
	void destroy(T* p)//负责对象析构
	{
		p->~T();//代表了T类型的析构函数
	}
};
template<typename T, typename Alloc = Allocator<T>>
class Vector
{
public:
	Vector(int size = 10)
	{
		//需要把内存开辟和对象构造分开处理
		//_first = new T[size];
		_first = _allocator.allocate(size);

		_last = _first;
		_end = _first + size;
	}

	~Vector()
	{
		//delete[]_first;
		//析构有效的元素,然后释放_first指针指向的堆内存
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作
		}
		_allocator.deallocate(_first);//释放堆上的数组内存
		_first = _last = _end = nullptr;
	}

	Vector(const Vector<T>& rhs)
	{
		int size = rhs._end - rhs._first;
		//_first = new T[size]; //空间大小
		_first = _allocator.allocate(size);
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}

		_last = _first + len;
		_end = _first + size;
	}
	Vector<T>& operator=(const Vector<T>& rhs) //拷贝构造
	{
		if (this == &rhs)return *this;
		//delete[] _first;
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作
		}
		_allocator.deallocate(_first);//释放堆上的数组内存

		int size = rhs._end - rhs._first;
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}
		_last = _first + len;
		_end = _first + size;
		return *this;
	}

	void push_back(const T& val)
	{
		if (full())
		{
			expand();
		}
		//*_last = val;
		_allocator.construct(_last, val);
		_last++;
	}

	void pop_back()
	{
		if (empty())
		{
			return;
		}
		//--_last;
		--_last;
		_allocator.destroy(_last);
	}
	T back()const //返回容器末尾的元素值
	{
		return *(_last - 1);
	}

	bool full()const { return _last == _end; }
	bool empty()const { return _first == _last; }
	int size()const { return _last - _first; }

private:

	void expand()
	{
		int _size = _end - _first;
		//T* tmp = new T[_size * 2];
		T* tmp = _allocator.allocate(2 * _size);
		for (int i = 0; i < _size; i++)
		{
			//tmp[i] = _first[i];
			_allocator.construct(tmp + i, _first[i]);
		}
		//delete[]_first;
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p);
		}
		_allocator.deallocate(_first);
		_first = tmp;
		_last = _first + _size;
		_end = _first + 2 * _size;
	}
	T* _first; //指向数组的起始的位置
	T* _last; //指向数组有效元素的后继位置
	T* _end; //指向数组空间的后继位置

	Alloc _allocator;//定义i容器中的空间配置项

};
//容器空间分配器
class Test
{
public:
	Test() { cout << "test()" << endl; }
	~Test() { cout << "~test()" << endl; }
	Test(const Test&) { cout << "Test(const Test&)" << endl; }
};

int main()
{
	Test t1, t2, t3;
	cout << "----------" << endl;
	Vector<Test>vec;

	vec.push_back(t1);
	vec.push_back(t2);
	vec.push_back(t3);
	cout << "----------" << endl;
	vec.pop_back(); //只需要析构
	cout << "----------" << endl;


	return 0;
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值