C/C++ 泛型编程与模板笔记

函数模板基本使用:

#include <iostream>
#include <typeinfo>

using namespace std;

// 逻辑非常相似,类型参数化,泛型编程,魔板变成
// 类型当参数穿进去。

template<class T> // 告诉编译器 下面如果出现T不要报错,T是一个通用的类型
void MySwap(T &x, T &y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

template<class T>
T MyAdd(T &x, T &y)
{
	return x + y;
}

// 此处的typename = class
template<typename T>
void MyPrint()
{
	T number;
	cout << "type = " << typeid(T).name() << endl;
}

int main(int argc, char *argv[])
{
	// 自动类型推导: 必须要有参数才能推到(根据参数来确定类型)
	int x = 10, y = 20;
	MySwap(x, y);
	cout << "x= " << x << endl;

	int ret = MyAdd(x, y);
	cout << "x+y = " << ret << endl;

	// 手动类型指定: 如果参数不一致,可能会报错,此时我们需要告诉它类型
	MySwap<int>(x, y);
	cout << "x= " << x << endl;

	// 针对无参数函数处理: 有些函数没有参数,我们需要指定模板默认类型
	MyPrint<int>();
	MyPrint<double>();

	system("pause");
	return 0;
}
#include <iostream>
#include <typeinfo>

using namespace std;

// 逻辑非常相似,类型参数化,泛型编程,魔板变成
// 类型当参数穿进去。

template<class T>
void MySwap(T &x, T &y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

template<class T>
void SelectSort(T Array[], int len)
{
	for (int x = 0; x < len; x++)
	{
		int max = x;
		for (int y = x + 1; y < len; y++)
		{
			if (Array[max] > Array[y])
				max = y;
		}
		if (max != x)
			MySwap(Array[max], Array[x]);
	}
}

template<class T>
void MyPrint(T Array[], int len)
{
	for (int x = 0; x < len; x++)
		cout << Array[x] << " ";
}

int main(int argc,char *argv[])
{
	int Int_Array[10] = { 4, 7, 8, 2, 1, 8, 0, 3, 2, 7 };
	SelectSort<int>(Int_Array, 10);
	MyPrint<int>(Int_Array, 10);

	char Char_Array[] = "hello lyshark";
	int len = sizeof(Char_Array) / sizeof (char);
	SelectSort<char>(Char_Array, len);
	MyPrint<char>(Char_Array, len);

	system("pause");
	return 0;
}

模板具体化 模板的局限性以及解决。通过自定义

#include <iostream>

using namespace std;

class Student
{
public:
	char *m_name;
	int m_age;
public:
	Student(char *name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
};

template<class Student>
bool MyCompare(Student &x, Student &y)
{
	if (x.m_age == y.m_age)
		return true;
	return false;
}


int main(int argc, char *argv[])
{
	Student stu1("lyshark", 22);
	Student stu2("admin", 33);

	bool ret = MyCompare(stu1, stu1);
	cout << ret << endl;

	bool ret1 = MyCompare(stu1, stu2);
	cout << ret1 << endl;

	system("pause");
	return 0;
}

类模板的使用: 类模板只能用显示指定类型,不支持自动推导

#include <iostream>
#include <string>

using namespace std;

template<class NameType = string,class AgeType = int>  // 类模板可以指定默认参数
class Student
{
public:
	string m_name;
	int m_age;

public:
	Student(NameType name,AgeType age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void show() { cout << "name = " << m_name << endl; }
};

template<class Student>
bool MyCompare(Student &x, Student &y)
{
	if (x.m_age == y.m_age)
		return true;
	return false;
}

int main(int argc, char *argv[])
{
	// 调用类模板是要在类后面添加参数列表
	Student<string, int> stu1("lyshark", 25);
	stu1.show();

	system("pause");
	return 0;
}

类模板做函数参数:

#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
public:
	string m_name;
	int m_age;

public:
	Student(NameType name,AgeType age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void show() { cout << "name = " << m_name << endl; }
};

void MyPrintA(Student<string, int> &ptr)
{ ptr.show(); }

template<class T1,class T2>
void MyPrintB(Student<T1,T2> &ptr)
{ ptr.show(); }

template<class T>
void MyPrintC(T &ptr)
{ ptr.show(); }

int main(int argc, char *argv[])
{
	// 1. 指定传入的类型直接调用
	Student<string, int> stu1("lyshark", 25);
	MyPrintA(stu1);

	// 2. 参数模板化调用
	Student<string, int> stu2("admin", 10);
	MyPrintB(stu2);

	// 3.整体模板化调用
	Student<string, int> stu3("root", 10);
	MyPrintC(stu3);

	system("pause");
	return 0;
}

类模板的类外实现:


#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
public:
	string m_name;
	int m_age;

public:
	Student(NameType name, AgeType age);
	void show();
};

// 类外实现成员构造函数
template <class NameType,class AgeType>
Student<NameType, AgeType>::Student(NameType name, AgeType age)
{
	this->m_name = name;
	this->m_age = age;
}

// 类外实现打印函数
template <class NameType,class AgeType>
void Student<NameType, AgeType>::show()
{
	cout << "Name = " << this->m_name << endl;
}

int main(int argc, char *argv[])
{
	Student<string, int> stu("lyshark", 20);
	stu.show();

	system("pause");
	return 0;
}

类模板友元函数类内实现:

#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
	// 友元函数的类内实现
	friend void show(Student<NameType, AgeType> &ptr)
	{
		cout << "name = " << ptr.m_name << endl;
	}

private:
	string m_name;
	int m_age;
public:
	Student(NameType name, AgeType age)
	{
		this->m_name = name;
		this->m_age = age;
	}
};


int main(int argc, char *argv[])
{
	Student<string, int> stu("lyshark", 20);
	// 此处调用,类似于全局调用
	show(stu);

	system("pause");
	return 0;
}

类模板友元函数类外实现:

#include <iostream>
#include <string>

using namespace std;

// 类外实现必须提前声明模板的存在
template<class T1, class T2> class Student;
template<class T1, class T2> void show(Student<T1, T2> & p);

template<class T1,class T2>
class Student
{
	// 友元函数类内实现,利用空参数列表声明 (占位符)
	friend void show<>(Student<T1, T2> &ptr);

private:
	string m_name;
	int m_age;

public:
	Student(T1 name, T2 age)
	{
		this->m_name = name;
		this->m_age = age;
	}
};

// 对友元函数的类外实现
template<class T1,class T2>
void show(Student<T1,T2> &ptr)
{
	cout << "name = " << ptr.m_name << endl;
}

int main(int argc, char *argv[])
{
	Student<string, int> stu("lyshark", 20);
	// 此处调用,类似于全局调用
	show(stu);

	system("pause");
	return 0;
}

C++ 结构化异常 (扩展)

简单的异常处理:

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
	try
	{
		throw 1;     // 抛出异常
	}
	catch (double)   // 捕获double异常
	{
		cout << "double" << endl;
	}
	catch (int)      // 捕获int异常
	{
		cout << "int" << endl;
	}
	system("pause");
	return 0;
}

自定义异常:

#include <iostream>
#include <string>

using namespace std;

class MyOutOfRangeException :public exception
{
public:
	string m_error;

public:
	MyOutOfRangeException(string errorInfo)
	{
		this->m_error = errorInfo;
	}
	virtual ~MyOutOfRangeException()
	{

	}
	virtual const char * what() const
	{
		// string 转char*
		return this->m_error.c_str();
	}
};

int main(int argc, char *argv[])
{
	try
	{
		throw MyOutOfRangeException("aa");   // 抛出异常
	}
	catch (MyOutOfRangeException &e)
	{
		cout << e.what() << endl;
	}

	system("pause");
	return 0;
}

使用系统标准异常:

#include <iostream>
#include <stdexcept>

using namespace std;

void init()
{
	while (1)
	{
		throw out_of_range("越界了");
	}
}

int main(int argc, char *argv[])
{
	try
	{
		init();
	}
	catch ( out_of_range &e)    // 抛出异常
	{
		cout << e.what() << endl;
	}

	system("pause");
	return 0;
}

捕获任意异常:

#include <iostream>
#include <stdexcept>

using namespace std;

void init()
{
	while (1)
	{
		throw out_of_range("越界了");
	}
}

int main(int argc, char *argv[])
{
	try
	{
		init();
	}
	catch ( ... )    // 抛出异常
	{
		cout << "aa" << endl;
	}


	system("pause");
	return 0;
}
posted @   lyshark  阅读(336)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

8952088 | 6896846
博客园 - 开发者的网上家园

点击右上角即可分享
微信分享提示