C++ class templates, nested class templates, template linked lists, dynamic arrays

C++ class templates, nested class templates, template linked lists, dynamic arrays

1. Class template

1. Writing of class templates

code show as below

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. Order requirements for class templates

There is an order requirement for specifying the default type, specifying it once from right to left, without interruption in the middle

code show as below

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

3. When there is a function template in the class template, implement the function outside

A function that uses a function template is defined in a class template

When implementing a function outside a class template that does not use a function template

Just write the class template

code show as below

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;
}

When implementing a function using a function template outside a class template

The class template should be first, and then the function template, the order cannot be reversed

code show as below

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;
}

2. Nested class template

Look at the following code for analysis

#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;
}

3. Template linked list

Turn a linked list into a template linked list

original linked list

#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;
}

Changed linked list

#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;
}

4. Dynamic array

Dynamic array:

1. Use a template to make the array a general type (any type of data can be stored)

2. When the size of the array is not enough, expand it by 1.5 times

code show as below

#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;
}

Guess you like

Origin blog.csdn.net/m0_73483024/article/details/132219718
Recommended