类模版

类模板基础语法

什么是类模板:
建立一个通用类,类中的成员,数据类型可以不具体指定,用一个虚拟的类型来代表

  • 语法:
template<typename T>
类
#include<iostream>
#include<string>
using namespace std;
template<class NameType, class AgeType>
class Person
{
private:
	NameType m_name;
	AgeType m_age;
public:
	Person(NameType name, AgeType age)
	{
		m_name = name;
		m_age = age;
	}
	void print()
	{
		cout << "姓名:" << m_name << " " << "年龄:" << m_age;
	}
};
void test()
{
	Person<string, int>p1("景元", 12);//注意:类模板只能显示指定类型,不能使用隐式类型推导
	p1.print();
}
int main()
{
	test();
	return 0;
}

类模板和函数模版的区别

  • 类模板没有自动类型推导的使用方式
  • 类模板在模版的参数列表中可以有默认参数

类模版中成员函数创建时机

类模板中成员函数和普通类中成员函数创建时机是有区别的:

  • 普通类中的成员函数一开始就可以创建
  • 类模版中的成员函数在调用时才开始创建

类模板对象做函数参数

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

#include<iostream>
#include<string>
using namespace std;


//类模板
template<class NameType, class AgeType>
class Person
{
private:
	NameType m_name;
	AgeType m_age;
public:
	Person(NameType name, AgeType age) :m_name(name), m_age(age)
	{

	}
	void display()
	{
		cout << m_name << " " << m_age << endl;
	}
};


//类模板做函数参数
void test01(Person<string, int>& p)
{
	p.display();
}
//参数模板化
template<class T, class R>
void test02(Person<T, R>& p)
{
	p.display();
}
//整个类模板化
template<class T>
void test03(T& p)
{
	p.display();
}
int main()
{
	Person<string, int> p1("飞霄", 19);
	test01(p1);
	Person<string, int> p2("镜流", 20);
	test02(p2);
	Person<string, int>p3("符华", 50000);
	test03(p3);
	return 0;
}

类模板与继承

如果父类是类模板,子类中需要指定父类类型

#include<iostream>
using namespace std;



//父类是类模板,子类指定父类类型继承
template<class T>
class Base1
{
public:
	T b;
};
class Son1 :public Base1<int>
{

};
//父类是类模板,子类也指定成类模板
template<class T>
class Base2
{
public:
	T b;
};

template<class T1, class T2>
class Son2 :public Base2<T1>
{
public:
	T2 s;
};
void test1()
{
	Son1 s;
	cout << typeid(s.b).name() << endl;
}
void test2()
{
	Son2<string, int> m;
	cout << "子类的成员的类型:" << typeid(m.s).name() << endl;
	cout << "父类成员的类型:" << typeid(m.b).name() << endl;

}
int main()
{
	test1();
	test2();
	return 0;
}

类模板成员函数类外实现

#include<iostream>
using namespace std;
template<class T1, class T2>
class Person
{
private:
	T1 m_name;
	T2 m_age;
public:
	Person(T1 name, T2 age);
	void display();
};
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
	this->m_name = name;
	this->m_age = age;
}
template<class T1, class T2>
void Person<T1, T2>::display()
{
	cout << "姓名:" << this->m_name << "\t年龄:" << this->m_age << endl;
}
void test01()
{
	Person<string, int>p1("镜流", 20);
	p1.display();
}
int main()
{
	test01();
	return 0;
}

类模板的分文件编写

将类模板的声明和实现都写在hpp中,然后main中包含hpp

类模板与友元

  • 全局函数访问模板类私有成员,类内实现
#include<iostream>
#include<string>
using namespace std;
/*
全局函数做友元访问私有成员:
1.类内直接实现,简单又方便
*/
template<class T1, class T2>
class Person
{
	//类内实现
	friend void display(Person<string, int>& p)
	{
		cout << "姓名:" << p.m_name << " " << "年龄:" << p.m_age << endl;
	}
private:
	T1 m_name;
	T2 m_age;
public:
	Person(T1 name, T2 age) :m_name(name), m_age(age)
	{

	}
};
void test01()
{
	Person<string, int>p("符玄", 400);
	display(p);
}
int main()
{
	test01();
	return 0;
}

  • 全局函数访问模板类私有成员,类外实现
    提前让编译器知道这个函数的存在
    注:md,因为这个比较麻烦,我其实没打算仔细写的,想着以后如果写类模版,需要全局友元函数的话,就在类内实现,没想到这次用类外实现,就补一下吧。

  • 给函数声明加上空模板参数列表

  • 让编译器提前知道全局函数

#include<iostream>
#include<string>
using namespace std;

template<class T, class E>
class Person;
template<class T, class E>
void printPerson(const Person<T, E>& p)
{
	cout << "姓名:" << p.m_name << " " << "年龄:" << p.m_age << endl;
}

template<class T, class E>
class Person
{
	friend void printPerson<>(const Person<T, E>& p);
public:
	Person(T name, E age) :m_name(name), m_age(age) {}
private:
	T m_name;
	E m_age;
};
void test()
{
	Person<string, int>p1("符玄", 200);
	printPerson(p1);
}
int main()
{
	test();
	return 0;
}

posted @ 2025-03-26 23:08  噫~该死的碳酸饮料  阅读(62)  评论(0)    收藏  举报