c++类模板,嵌套类模板,模板链表,动态数组

c++类模板,嵌套类模板,模板链表,动态数组

一.类模板

1.类模板的书写

代码如下

template<typename T>//模板
class CTest {//类
public:
	T m_a;

	CTest(const T&a):m_a(a){}

	void fun1() {
		cout << typeid(m_a).name() << "   " << m_a << endl;
	}
};

int main() {
	//进行调用测试
	CTest<int> tes(5);//在定义对象时 显示指定
	tes.fun1();

	CTest2<> tes2(5);//用类模板定义对象时<> 不能省略
	tes2.fun1();
	return 0;
}

2.类模板的顺序要求

指定默认的类型有顺序要求,从右到左一次指定,中间不得有间断

代码如下

template<typename T=int, typename K=char>//正确的写法

3.当类模板中有函数模板时,在外面进行函数实现

在类模板里定义了使用了函数模板的函数

在类模板外进行实现没使用函数模板的函数的时候

只写类模板就可以

代码如下

template<typename T=int>
class CTest {
public:
	T m_a;

	CTest(const T& a) :m_a(a) {}

	void fun1();

	template<typename K=char>
	void fun2(K k);
};

template<typename T>
void CTest<T>::fun1() {
	cout << typeid(m_a).name() << "   " << m_a << endl;
}

在类模板外进行实现使用了函数模板的函数的时候

要先类模板,后函数模板,顺序不能反

代码如下

template<typename T=int>
class CTest {
public:
	T m_a;

	CTest(const T& a) :m_a(a) {}

	void fun1();

	template<typename K=char>
	void fun2(K k);
};

template<typename T>//类模板
template<typename K>//函数模板
void CTest<T>::fun2(K k) {
	cout << typeid(m_a).name() << "   " << m_a << endl;
	cout << typeid(k).name() << "   " << k << endl;
}

二.嵌套类模板

看如下代码进行分析

#include <iostream>
using namespace std;

template<typename T>
class A {
public:
	T m_a;
	A(const T&a):m_a(a){}

};


class B {
public:
	A<int> aa;
	B():aa(1) {//调用了A的构造函数

	}
};

template<typename K>
class C {
public:
	A<K> aa;
	C(const A<K>& a):aa(a){}//调用了A的拷贝函数
};

template<typename M>
class D {
public:
	M m_m;
	D(const M& m) :m_m(m) {}//调用了A的拷贝函数
};


int main() {

	B tes;
	cout << typeid(tes.aa.m_a).name() << "   "<< tes.aa.m_a <<endl;

	C<char> cc(A<char>('a'));
	cout << typeid(cc.aa.m_a).name() << "   " << cc.aa.m_a << endl;

	D<  A<char> > dd(A<char>('a'));
	cout << typeid(dd.m_m.m_a).name() << "   " << dd.m_m.m_a << endl;
	return 0;
}

三.模板链表

将一个链表变为模板链表

原链表

#include <iostream>
using namespace std;

//节点
struct Node {
	int m_v;
	Node* m_pNext;
	Node(int v) {
		m_v = v;
		m_pNext = nullptr;
	}
};

//迭代器
class Citerator {
public:
	Node* Temp;
	Citerator(Node* m_pHead) :Temp(m_pHead) {

	}

	bool operator!=(Node* m_pHead) {
		return Temp != m_pHead;
	}

	operator bool() {
		return Temp;
	}

	int operator*() {
		return Temp->m_v;
	}

	Node* operator++() {
		Temp=Temp->m_pNext;
		return Temp;
	}

	Node* operator++(int) {
		Node* temp = Temp;
		Temp = Temp->m_pNext;
		return temp;
	}

};

//链表
class Clist {
public:
	Node* m_pHead;
	Node* m_pEnd;
	int m_nLen;
public:

	void showClist() {
		Citerator ite(m_pHead);//构造
		while (ite!=nullptr) { //operator!=  operator==  operator bool
			cout << *ite << "    ";//operator*
			ite++;//operator++
		}
		cout << endl;
	}


	Clist() {
		m_pHead = m_pEnd = nullptr;
		m_nLen = 0;
	}
	~Clist() {
		Node* pTemp = nullptr;
		while (m_pHead) {
			pTemp = m_pHead;
			m_pHead = m_pHead->m_pNext;

			delete pTemp;
			pTemp = m_pHead = m_pEnd = nullptr;
			m_nLen = 0;
		}
	}
	void pushBack(int v) {
		Node* p_Node = new Node(v);
		if (m_pHead) {
			m_pEnd->m_pNext = p_Node;
			m_pEnd = p_Node;
		}
		else {
			m_pHead = m_pEnd = p_Node;

		}
		++m_nLen;
	}

	void clearFront() {
		if (m_pHead) {
			Node* Temp = m_pHead;
			if (m_nLen == 1) {
				m_pHead = m_pEnd = nullptr;
			}
			else {
				m_pHead = m_pHead->m_pNext;

			}
			delete Temp;
			Temp = nullptr;
			--m_nLen;
		}
	}
	
	int Clistlen() {
		return m_nLen;
	}
};

int main() {

	Clist pro;
	pro.pushBack(1);
	pro.pushBack(2);
	pro.pushBack(3);
	pro.pushBack(4);
	pro.pushBack(5);

	pro.showClist();
	cout << pro.m_nLen << endl;

	pro.clearFront();
	pro.clearFront();
	pro.clearFront();
	pro.clearFront();
	pro.showClist();
	cout << pro.m_nLen << endl;
	return 0;
}

更改后的链表

#include <iostream>
using namespace std;

//节点
template<typename T>//1
struct Node {
	T m_v; //2
	Node* m_pNext;
	Node(const T& v):m_v (v), m_pNext(nullptr){//3
	}
};

//迭代器
template<typename M>//4
class Citerator {
public:
	Node<M>* Temp;//5
	Citerator(Node<M>* m_pHead) :Temp(m_pHead) {}//6

	bool operator!=(Node<M>* m_pHead) {//7
		return Temp != m_pHead;
	}

	operator bool() {
		return Temp;
	}

	M& operator*() {//8 返回类型为引用,返回的就是当前类对象的变量
		return Temp->m_v;
	}

	Node<M>* operator++() {//9
		Temp=Temp->m_pNext;
		return Temp;
	}

	Node<M>* operator++(int) {//10
		Node<M>* temp = Temp;//11
		Temp = Temp->m_pNext;
		return temp;
	}

};

//链表
template<typename K>//12
class Clist {
public:
	Node<K>* m_pHead;//13
	Node<K>* m_pEnd;//14
	int m_nLen;
public:
	
	void showClist() {
		Citerator<K> ite(m_pHead);//构造
		while (ite!=nullptr) { //operator!=  operator==  operator bool
			cout << *ite << "    ";//operator*
			ite++;//operator++
		}
		cout << endl;
	}


	Clist() {
		m_pHead = m_pEnd = nullptr;
		m_nLen = 0;
	}
	~Clist() {
		Node<K>* pTemp = nullptr;//15
		while (m_pHead) {
			pTemp = m_pHead;
			m_pHead = m_pHead->m_pNext;

			delete pTemp;
			pTemp = m_pHead = m_pEnd = nullptr;
			m_nLen = 0;
		}
	}
	void pushBack(K v) {//16
		Node<K>* p_Node = new Node<K>(v);//17
		if (m_pHead) {
			m_pEnd->m_pNext = p_Node;
			m_pEnd = p_Node;
		}
		else {
			m_pHead = m_pEnd = p_Node;

		}
		++m_nLen;
	}

	void clearFront() {
		if (m_pHead) {
			Node<K>* Temp = m_pHead;//18
			if (m_nLen == 1) {
				m_pHead = m_pEnd = nullptr;
			}
			else {
				m_pHead = m_pHead->m_pNext;

			}
			delete Temp;
			Temp = nullptr;
			--m_nLen;
		}
	}
	
	int Clistlen() {
		return m_nLen;
	}
};

//自定义类型
class CTest {
public:
	int m_a;
	CTest():m_a(10){}
	CTest(int a):m_a(a) {}
};

ostream& operator<<(ostream& os, CTest& tst) {
	os << tst.m_a;
	return os;
}
int main() {
	
    //样例测试
    
	//Clist<double> pro;
	//pro.pushBack(1.1);
	//pro.pushBack(2.1);
	//pro.pushBack(3.1);
	//pro.pushBack(4.1);
	//pro.pushBack(5.1);

	//pro.showClist();
	//cout << pro.m_nLen << endl;

	//pro.clearFront();
	//pro.clearFront();
	//pro.clearFront();
	//pro.clearFront();
	//pro.showClist();
	//cout << pro.m_nLen << endl;

	//自定义类型的测试
	Clist<CTest> pro;
	pro.pushBack(CTest());
	pro.pushBack(CTest());
	pro.pushBack(CTest());
	pro.pushBack(CTest(5));
	pro.pushBack(CTest(57));

	pro.showClist();
	cout << pro.m_nLen << endl;

	pro.clearFront();
	pro.clearFront();
	pro.clearFront();
	pro.clearFront();
	pro.showClist();
	cout << pro.m_nLen << endl;
	return 0;
}

四.动态数组

动态数组:

1.用模板使该数组变为通用类型(可以存任意一种类型的数据)

2.当数组大小不够时,以1.5倍扩容

代码如下

#include <iostream>
using namespace std;

/*
	动态数组:可以存任意一种类型数据所以要用到模板
			当数组大小不够时,以1.5倍扩容
*/

template<typename T>
class CDynamicArray {
public:
	T * array;
	int m_size;  //使用量
	int m_rongliang;  //容量
public:
	CDynamicArray(int rongliang=0):array(nullptr), m_size(0), m_rongliang(0){//动态数组的初始化
		if (rongliang > 0) {
			array = new T[rongliang];
			m_size = 0;
			m_rongliang = rongliang;
		}
		
	}
	~CDynamicArray() {//最后结束回收空间
		if (array) {
			delete[]array;
		}
		m_size = 0;
		m_rongliang = 0;
	}
public:
	void PushBack(const T& t) {
		if (m_size >= m_rongliang) {//容量不够,进行扩容
			int Temp = m_rongliang + 1;
			m_rongliang = (m_rongliang + m_rongliang / 2)> Temp? (m_rongliang + m_rongliang / 2): Temp;
			T* Newarray = new T[m_rongliang];
			for (int i = 0; i < m_size; i++) {
				Newarray[i] = array[i];
			}
			delete[]array; 
			array = Newarray;
		}
		array[m_size++] = t;
	}


	void PopBack() {//删除动态数组尾部元素
		if (m_size) m_size -= 1;
	}

	void ShowArray() {//遍历一遍动态数组元素
		for (int i = 0; i < m_size; i++) {
			cout << array[i] << "   ";
		}
		cout << endl;
	}

	int GetLength() {//获取动态数组的长度(使用量)
		return m_size;
	}

	T& operator[](int index) {//重载[],可以直接通过类对象名[]的方式获得元素的值
		return array[index];
	}

	T* begin() {//手写begin()函数,和end()函数,这样就可以使用for的范围遍历了
		return &array[0];
	}

	T* end() {
		return &array[m_size];
	}

};

int main() {
	//样例测试
	CDynamicArray<int> arr;
	arr.PushBack(1);
	arr.PushBack(2);
	arr.PushBack(3);
	arr.PushBack(4);
	arr.PushBack(5);
	arr.ShowArray();
	cout << arr.GetLength() << endl;
	arr.PopBack();
	arr.PopBack();
	arr.ShowArray();
	cout << arr[0] << endl;

	for (int i = 0; i < arr.GetLength(); i++) {
		cout << arr[i] << "   ";
	}
	cout << endl;
	
	for (int v : arr) {
		cout << v << "   " ;
	}
	cout << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_73483024/article/details/132219718
今日推荐