类模板

1、类模板定义

#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;


template<typename NameType,typename AgeType>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
	public:
		Person(NameType name,AgeType age)
		{
			this->name=name;
			this->age=age;
		}
		
		void showPerson()
		{
			cout<<name<<"   "<<age<<endl;
		}
		NameType name;
		AgeType age;
};
int main()
{
    Person<string,int> p1("孙悟空",999);
    p1.showPerson();
    return 0;
}

2、类模板和函数模板区别:

  1. 类模板没有自动类型推导的使用方式
  2. 类模板在模板参数列表中可以有默认参数
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;


template<typename NameType,typename AgeType=char>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
	public:
		Person(NameType name,AgeType age)
		{
			this->name=name;
			this->age=age;
		}
		
		void showPerson()
		{
			cout<<name<<"   "<<age<<endl;
		}
		NameType name;
		AgeType age;
};
int main()
{
    Person<string,int> p1("孙悟空",99);
    Person<string> p2("孙悟空",99);
    p1.showPerson();
    p2.showPerson();
    return 0;
}

 3、类模板中成员函数调用时机

类模板中成员函数在调用时才去创建

#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;



class Person1
{
	public:
		void showPerson1()
		{
			cout<<"Person1:show"<<endl;
		}
};
class Person2
{
	public:
		void showPerson2()
		{
			cout<<"Person2:show"<<endl;
		}
};

template<typename T>  
class MyClass
{
	public:
		T obj;
		void func1()
		{
			obj.showPerson1();
		}
		void func2()
		{
			obj.showPerson2();
		}
};
int main()
{
    MyClass<Person1>p1;
    p1.func1();
    
    MyClass<Person2>p2;
    p2.func2();
    return 0;
}

4、类模板对象做函数参数

  1. 指定传入类型
  2. 参数模板化
  3. 整个类模板化

#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<typeinfo>
using namespace std;


template<typename NameType,typename AgeType>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
	public:
		Person(NameType name,AgeType age)
		{
			this->name=name;
			this->age=age;
		}
		
		void showPerson()
		{
			cout<<name<<"   "<<age<<endl;
		}
		NameType name;
		AgeType age;
};
//指定传入类型
void printfPerson1(Person<string,int> &p)
{
	p.showPerson();
}
//参数模板化
template<typename NameType,typename AgeType>
void printfPerson2(Person<NameType,AgeType> &p)
{
	p.showPerson();
	cout<<"NameType的类型为:"<<typeid(NameType).name()<<endl;
	cout<<"AgeType的类型为:"<<typeid(AgeType).name()<<endl;
}
//整个类模板化
template<typename T>
void printfPerson3(T &p)
{
	p.showPerson();
	cout<<"T的类型为:"<<typeid(T).name()<<endl;
}

int main()
{
	
    Person<string,int> p1("孙悟空",999);
    printfPerson1(p1);
    
    Person<string,int> p2("猪八戒",99);
    printfPerson2(p2);
    
    Person<string,int> p3("唐僧",20);
    printfPerson3(p3);
    return 0;
}

5、类模板的继承

如果父类时类模板,子类需要明确模板数据类型或者也写成类模板

#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<typeinfo>
using namespace std;


template<typename T>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Base
{
	public:
		T m;
};

class Son:public Base<int>
{
	
};

template<typename T1,typename T2>
class Son2:public Base<T2>
{
	T1 obj;
};
int main()
{
	
    Son s1;
    
    Son2<string,int> s2; 
    return 0;
}

6、类模板成员函数类外实现

#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;


template<typename NameType,typename AgeType>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
	public:
		Person(NameType name,AgeType age);
		
		
		void showPerson();
		
		NameType name;
		AgeType age;
};

template<typename T1,typename T2>
Person<T1,T2>::Person(T1 name,T2 age)
{
	this->name=name;
	this->age=age;
}

template<typename T1,typename T2>
void Person<T1,T2>::showPerson()
{
	cout<<name<<"   "<<age<<endl;
}
int main()
{
    Person<string,int> p1("孙悟空",999);
    p1.showPerson();
    return 0;
}

7、类模板分文件编写

不能#include"Person.h",因为类模板中成员函数在调用时才去创建,这就导致在链接阶段,编译器根本没看"Person.cpp"中成员函数的实现。

解决方法:

  1. 直接包含源文件 #include"Person.cpp"
  2. 将.h和.cpp中的内容写到一起,将后继名改为.hpp文件 #include"Person.hpp"

8、类模板与友元

  1.  全局函数类内实现:直接在类内声明友元即可
  2. 全局函数类外实现:需要提前让编译器知道全局函数的存在
#include<iostream>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;

template<typename NameType,typename AgeType> 
class Person;

template<typename NameType,typename AgeType>
void printPerson2(Person<NameType,AgeType> p)
{
	cout<<p.name<<"    "<<p.age<<endl;
}

template<typename NameType,typename AgeType>  //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
class Person
{
	friend void printPerson(Person<NameType,AgeType> p)
	{
		cout<<p.name<<"    "<<p.age<<endl;
	}
	friend void printPerson2<>(Person<NameType,AgeType> p);
public:
	Person(NameType name,AgeType age);
	
	NameType name;
	AgeType age;
};

template<typename T1,typename T2>
Person<T1,T2>::Person(T1 name,T2 age)
{
	this->name=name;
	this->age=age;
}


int main()
{
    Person<string,int> p1("孙悟空",999);
    printPerson2(p1);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值