C++笔记(自定义模板)

//盛夏白瓷梅子汤,碎冰破壁叮咚响
2020.6.7 苏
预备tips:
①形如int arr[10],double b[2]即可创建数组
②//用new申请的动态内存可以用delete释放
int *ptr1 = new int [3];
delete ptr1;//仅删除ptr1[0]
int *ptr2 = new int [3];
delete []ptr2;//释放整个对象数组指针指向的内存
③模板类的接口和实现(类定义和类实现(成员函数定义)放在同一个头文件中)
一.基础知识
1.创建类模板
#include//双队列deque对象是堆栈Stack的默认适配器
template //类型形参表中关键词typename与class可以互换;多个形参的类型形参表形如
class Stack // Stack只能对栈顶进行插入删除操作
{
public:
T&top()
{return stack.front()}//返回一个栈顶元素的引用

void push(const T& value)
{stack.push_front(value)}//在栈顶加一个元素

void pop()
{stack.pop_front();}//删除栈顶元素

bool isEmpty() const
{ return stack.empty();}//堆栈为空则返回1

size_t size() const
{ return stack.size();}//返回元素个数
2.可以在类模板定义之外声明类模板成员函数
函数定义格式如下
template
inline void Stack::pop()//Stack的默认形参在函数定义中不必声明

{stack.pop_front();}
3.测试类模板
①Stack doubleStack;//创建实例化的类对象
或者Stack intStack
//即在类声明之外出现类名的地方都要用 类名;实例化时用如 类名
②while( !intstack.isEmpty() )
{
cout< intstack.pop();
}
4.使用函数模板来操作类模板实例化的对象
①当创建好类模板实例化对象后,可以在驱动程序里定义函数类模板,以实例化对象为形参。
②#include
template//注:这段发生在main函数前
void testStack(Stack&theSatck, const T&value, size_t size)//函数形参表中至少一个形参为类型形参表中的形参
{ …; } //模板函数不支持默认模板形参
③函数模板实例化
template
void swap(T&a,T&b)
swap(a,b){…};//对于成员模板函数调用时用 对象名.swap(a,b){…};
5.形参
①使用非类型(模板)形参,可以有默认的实参作为常量处理
1°模板声明的开始部分为template
比如对array类模板进行特化用arrayarr;
2°可以有缺省参数
例一:template//类型形参实例化为类型,普通形参实例化为数据
Stackstack;用了默认参数便是Stackstack;
例二:template
Stack<>stack;
//注意C++标准库中Stack模板开始部分为template
//即默认下stack对象用deque对象保存satck对象的元素,可声明为Stackvalues;

二.强化知识
1.类A可以声明为模板类B特化的友元
【例题1】:
template
class linkedstack;
//完成链栈类声明

//完成类Node定义
template<typename T>
class Node
{
	friend linkedStack<T>//声明特化友元
private:
	T data;
	Node<T>* link;//该指针作用为  指向链栈中向底部的下一个Node元素
};
```cpp
//完成自定义类型linkedStack的输出重载
template<typename T>
ostream& operator<<(ostream& out, linkedStack<T>& s)
{
	T elem;
	while (!s.isEmpty())
	{
		s.Delete(elem)//先把栈顶元素赋值给elem,再删去栈顶元素
			out << elem << endl;
	}
	return out;
}

```cpp
//完成自定义类linkedStack的定义
template<class T>
class linkedStack//链栈中每个元素都是Node类对象
{
	friend ostream& operator<<(ostream&, linkedStack<T>&)//将自己的输出重载声明为友元函数
private:Node<T>* top;
public:
	linkedStack() { top = 0; }//刚声明类对象时使top指针不指向任何地方
	~linkedStack();//每次析构删去一个栈顶,top指向原栈顶下面一个元素。一会儿在类定义外定义析构函数。
	bool isEmpty()const
	{
		return top == NULL
	}
	linkedStack<T>& Add(T& x);
	linkedStack<T>& Delete(T& x);
	}
//完成类定义外对Add成员函数的定义
template<class T>
linkedStack<T>& linkedStack<T>::Add(const T& x)
{
	Node<T>* p = new Node<T>;
	p->data = x;
	p->link = top;//新顶元素link指针指向原top指针指向的元素,即新顶元素的link指向原顶元素
	top = p;//top指向新顶元素
	return *this;
}
//完成类定义外对Delete成员函数的定义
linkedStack<T>& linkedStack<T>::Delete(T& x)
{
	Node<T>* tempp = NULL;
	x = top->data;//在弹出栈顶元素前先把它赋值给x,以备后用
	tempp = top->link;
	delete top;
	return *this;
}
////完成类定义外对析构函数的定义
template<class T>
linkedStack<T>::~linkedStacked()
{
	Node<T>* next;
	while (top!=0)
	{
		next = top->link;
		delete top;
		top = next;
	}//释放整个对象内存
}

【例题2:使用int模板非类型参数numberOfElements和类型参数elementType来帮助创建数组类的模板。此模板将允许在编译时用指定元素类型的指定数量的元素实例化数组对象。】

#include
#include
using namespace std;
template<typename elementType, int numberOfElements>
class Array
{
private:
	elementType* ptr;//创建指针
public:
	Array()
	{
		ptr = new elementType[numberOfElements];//在构造函数中建立好确定大小的数组指针ptr,即指向数组的指针。
		//指向numberOfElement个元素。
	}
	~Array()
	{
		delete[]ptr;//删除ptr指向的整个数组内存
	}
	int getnumberOfElements()const
	{
		return numberOfElements;
	}
	template<typename T1, int a>//自定义类型Array的输入输出重载
	friend std::ostream& operator<<(ostream& os, Array<T1, a>& rhs);

	template<typename T2, int b>
	friend std::istream& operator>>(istream& in, Array<T2, b>& rhs);
};
template<typename T, int a>
std::ostream& operator<<(ostream& os, Array<T, a>& rhs)
{
	for (int i = 0;i < a;i++)
		os << rhs.ptr[i] << " ";//数组指针名即数组名,再体会一下。创建了指针数组相当于创建了数组。
	return os;
}
template<typename T, int a>
std::istream& operator>>(istream& in, Array<T, a>& rhs)
{
	for (int i = 0;i < a;i++)
		in >> rhs.ptr[i];
	return in;
}
int main()
{
	cout << "Enter 5 integer values :\n";
	Array<int, 5>a;
	cin >> a;
	cout <<"The values in the intArray are : " <<a << endl;

	cout << "Enter 7 one - word string values :\n";
	Array<string, 7>b;
	cin >> b;
	cout << "The values in the stringArray are : " << b << endl;
	system("pause");
}

`

你可能感兴趣的:(C++笔记)