栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++类模板

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++类模板

01 类模板语法

#include
using namespace std;
//类模板

template
class Person
{
public:
	NameType m_Name;
	AgeType m_Age;

public:
	Person(NameType name, AgeType age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	void ShowPerson()
	{
		cout << "name:" << this->m_Name << " age:" << this->m_Age << endl;
	}
};

void _01Test01()
{
	 Person p("Tom", 18);//<  >中就相当于模板形参列表
	 p.ShowPerson();
}

void main()
{
	_01Test01();
}

02 类模板与函数模板的区别

//1、类模板没有自动类型推导的使用方式
//2、类模板在模板参数列表中可以有默认类型参数 函数模板不可以使用默认类型参数

#include
using namespace std;
#include 

//类模板与函数模板的区别
//1、类模板没有自动类型推导的使用方式
//2、类模板在模板参数列表中可以有默认类型参数 函数模板不可以使用默认类型参数
template
class _02Person
{
public:
	NameType m_Name;
	AgeType m_Age;

public:
	_02Person(NameType name, AgeType age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	void ShowPerson()
	{
		cout << "name:" << this->m_Name << " age:" << this->m_Age << endl;
	}
};

//1、类模板没有自动类型推导的使用方式
void _02Test01()
{
	//_02Person p("Tom", 19);//报错 类模板中没有自动类型推导

	_02Person p("Tom", 19);
	p.ShowPerson();
}

//2、类模板在模板参数列表中可以有默认类型参数 
void _02Test02()
{
	//使类模板参数列表中的AgeType默认等于int
	_02Person p1("Tony", 20);
	p1.ShowPerson();

	_02Personp2("Jack", "22");
	p2.ShowPerson();
}

void main()
{
	//_02Test01();
	_02Test02();
}

03 类模板中成员函数的创建时机

//类模板中的成员函数并不是一开始就创建的 而是在模板调用时才创建

#include 
using namespace std;

//类模板中成员函数的创建时机
//类模板中的成员函数并不是一开始就创建的 而是在模板调用时才创建
class Person1
{
public:
	void showPerson1()
	{
		cout << "调用showPerson1" << endl;
	}
};

class Person2
{
public:
	void showPerson2()
	{
		cout << "调用showPerson2" << endl;
	}
};

template
class MyClass
{
public:
	T obj;
public:
	void func1()
	{
		obj.showPerson1();
	}

	void func2()
	{
		obj.showPerson2();
	}
};

void _03Test01()
{
	MyClass myClass;
	myClass.func1();
	//myClass.func2();//编译报错 说明函数调用时才会去创建成员函数

}

void main()
{
	_03Test01();
}

04 类模板对象做函数参数

//1、指定传入类型

//2、参数模板化

//3、整个类模板化 使用比较广泛

#include
using namespace std;
#include

//类模板对象做函数参数
template
class _04Person
{
public:
	T1 m_Name;
	T2 m_Age;

	_04Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	void showPerson()
	{
		cout << "name:" << this->m_Name << " age:" << this->m_Age << endl;
	}

};

//1、指定传入类型
void PrintPerson1(_04Person& p)
{
	p.showPerson();
}
void _04Test01()
{
	_04Person p("Tom", 19);
	PrintPerson1(p);
}

//2、参数模板化
template
void PrintPerson2(_04Person& p)
{
	cout << "T1类型:" << typeid(T1).name() <<  endl;
	cout << " T2类型:" << typeid(T2).name() << endl;
	p.showPerson();
}

void _04Test02()
{
	_04Person p("Tony", 29);
	PrintPerson2(p);
}

//3、整个类模板化 使用比较广泛'
template
void PrintPerson3(T& p)
{
	cout << "T的类型为:" << typeid(T).name() << endl;
	p.showPerson();
}
void _04Test03()
{
	_04Person p("Jack", 39);
	PrintPerson3(p);
}

void main()
{
	_04Test01();
	_04Test02();
	_04Test03();
}

05 类模板与继承

//当类模板碰到继承时,需要注意以下几点:
//1、当子类继承的父类为类模板时,子类在声明时,必须指定父类中T的类型
//2、如果不指定,编译器无法给子类分配内存
//3、如果想灵活指定出父类中T的类型,子类也需要变为类模板

#include 
using namespace std;
//当类模板碰到继承时,需要注意以下几点:
//1、当子类继承的父类为类模板时,子类在声明时,必须指定父类中T的类型
//2、如果不指定,编译器无法给子类分配内存
//3、如果想灵活指定出父类中T的类型,子类也需要变为类模板

//类模板与继承
template
class Base
{
public:
	T m_Member;

};


//如果不指定,编译器无法给子类分配内存
//class Son1:Base//报错 没有指明父类中T的数据类型
class Son1 :Base
{

};


//如果想灵活指定出父类中T的类型,子类也需要变为类模板
template
class Son2 :Base
{
public:
	T2 m_Member2;

	Son2()
	{
		cout << "T1的类型为:" << typeid(T1).name() << endl;
		cout << "T2的类型为:" << typeid(T2).name() << endl;
	}

};

void _05Test01()
{
	Son2 s;
}

void main()
{
	_05Test01();
}

06 类模板成员函数类外实现

#include
using namespace std;
//类模板成员函数类外实现
template
class Student
{
public:
	T1 m_Name;
	T2 m_Age;

	Student(T1 name, T2 age);

	void showStudent();
};

template
Student::Student(T1 name, T2 age)
{
	this->m_Name = name;
	this->m_Age = age;
}

template
void Student::showStudent()
{
	cout << "姓名;" << this->m_Name << " 年龄:" << this->m_Age << endl;
}


void _06Test01()
{
	Students1("Tom", 19);
	s1.showStudent();
}

void main()
{
	_06Test01();
}

07 类模板分文件编写

//类模板份文件编写问题和解决方法
//问题:
//类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到

//解决方法:
//方式1:直接包含.cpp源文件
//方式2:将声名和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制

hpp文件:

#pragma once
#include
using namespace std;
template
class _07Person
{
public:
	T1 m_Name;
	T2 m_Age;

	_07Person(T1 name, T2 age);

	void showPerson();
};

template
_07Person::_07Person(T1 name, T2 age)
{
	this->m_Name = name;
	this->m_Age = age;
}


template
void _07Person::showPerson()
{
	cout << "name:" << this->m_Name << " age:" << this->m_Age << endl;
}
#include

using namespace std;

//类模板份文件编写问题和解决方法
//问题:
//类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到

//解决方法:
//方式1:直接包含.cpp源文件
//#include"person.cpp"


//方式2:将声名和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制
#include"person.hpp"

void _07Test01()
{
	_07Person p("Tom", 18);
	p.showPerson();
}

void main()
{
	_07Test01();

}

08 类模板与友元

#include
using namespace std;

//在编写友元函数实现之前还要提前声明类模板
template
class _08Person;

//友元函数类外实现需要在类之前编写实现
template
void showPerson2(_08Person p)
{
	cout << "name: " << p.m_Name << " age:" << p.m_Age << endl;
}


template
class _08Person
{
	//友元函数类内实现
	friend void showPerson1(_08Person p)
	{
		cout << "name: " << p.m_Name << " age:" << p.m_Age << endl;
	}

	//友元函数类外实现 还需要加空模板参数列表
	//如果全局函数是类外实现,还需要让编译器提前知道这个函数的存在
	friend void showPerson2<>(_08Person p);

public:
	T1 m_Name;
	T2 m_Age;

	_08Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

};

void _08Test01()
{
	_08Personp("Jerry", 19);

	showPerson1(p);
}

void _08Test02()
{
	_08Personp("Jack", 20);

	showPerson2(p);
}

void main()
{
	//_08Test01();
	_08Test02();

}

09 类模板案例-通用数组类封装

MyArray.hpp文件:

//自己的通用的数组类
#pragma once
#include 
#include "MyArray.hpp"
using namespace std;


template
void PrintArray(MyArray& arr)
{
	for (int i = 0; i < arr.getSize(); i++)
	{
		cout << arr[i] << endl;
	}
}

void _09Test01()
{
	MyArray arr1(5);

	for (int i = 0; i < 5; i++)
	{
		arr1.Push_Back(i);
	}

	cout << "arr1的打印输出:" << endl;
	PrintArray(arr1);
}

void _09Test02()
{
	MyArray arr(10);

	arr.Push_Back("小一");
	arr.Push_Back("小二");
	arr.Push_Back("小三");
	arr.Push_Back("小四");
	arr.Push_Back("小五");

	PrintArray(arr);
	cout << "容量" << arr.getCapacity() << endl;
	cout << "数量" << arr.getSize() << endl;
}

void main()
{
	_09Test01();

	_09Test02();
}

测试文件:

//自己的通用的数组类
#pragma once
#include 
#include "MyArray.hpp"
using namespace std;


template
void PrintArray(MyArray& arr)
{
	for (int i = 0; i < arr.getSize(); i++)
	{
		cout << arr[i] << endl;
	}
}

void _09Test01()
{
	MyArray arr1(5);

	for (int i = 0; i < 5; i++)
	{
		arr1.Push_Back(i);
	}

	cout << "arr1的打印输出:" << endl;
	PrintArray(arr1);
}

void _09Test02()
{
	MyArray arr(10);

	arr.Push_Back("小一");
	arr.Push_Back("小二");
	arr.Push_Back("小三");
	arr.Push_Back("小四");
	arr.Push_Back("小五");

	PrintArray(arr);
	cout << "容量" << arr.getCapacity() << endl;
	cout << "数量" << arr.getSize() << endl;
}

void main()
{
	_09Test01();

	_09Test02();
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/968989.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号