c++_类模板及拓展详解

本文详细介绍了C++中的类模板参数化,包括直接传入模板对象、类模板传入方式以及整个类模板化的三种方法,并通过实例代码进行了演示。此外,还探讨了类模板的继承,包括四种不同的继承形式。最后,讲解了类模板成员函数的类外实现以及友元函数的使用,包括类外实现友元和类内实现。文章旨在深入理解C++模板的高级特性。
摘要由CSDN通过智能技术生成

一、  类模板对象当做函数的参数

格式:
 //第一种方式,直接传入模板对象
void fun(person<string, int>& per)

案例:

#include<iostream>
using namespace std;
#include<string>
 
//类模板
template<class NameType,class AgeType>
class Person {
	public:
		Person(NameType name,AgeType age) {
			this->m_age=age;
			this->m_name=name;
		}
		void showPerson() {
			cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
		}
	public:
		NameType m_name;
		AgeType m_age;
};
 
//1.指定传入的类型
void printPerson(Person<string,int> &p)
{
	p.showPerson();
}
void test01() 
{
	Person<string,int>p("strangeDoc",100);
	printPerson(p);
}
int main() 
{
	test01();
	system("pause");
	return 0;
}

//第二种方式,类模板传入方式
格式:

template <class T1,class T2>
void fun3(person<T1,T2>& per)

案例:

#include<iostream>
using namespace std;
#include<string>
#include<typeinfo>
 
//类模板
template<class NameType,class AgeType>
class Person {
	public:
		Person(NameType name,AgeType age) {
			this->m_age=age;
			this->m_name=name;
		}
		void showPerson() {
			cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
		}
	public:
		NameType m_name;
		AgeType m_age;
};
 
//2.参数模板化
template<class T1,class T2>
void printPerson02(Person<T1,T2> &p)
{
	p.showPerson();
	//cout<<"T1的类型为:"<<typeid(T1).name()<<endl;
	//cout<<"T2的类型为:"<<typeid(T2).name()<<endl;
}
void test02()
{
	Person<string,int>p("capitain",90);
	printPerson02(p);
 } 
int main() 
{
	test02();
	system("pause");
	return 0;
}

//第三种方式,整个类模板化

格式:
template <class T>
void fun4(T& per)

案例:

#include<iostream>
using namespace std;
#include<string>
#include<typeinfo>
 
//类模板
template<class NameType,class AgeType>
class Person {
	public:
		Person(NameType name,AgeType age) {
			this->m_age=age;
			this->m_name=name;
		}
		void showPerson() {
			cout<<"姓名:"<<this->m_name<<"年龄:"<<this->m_age<<endl;
		}
	public:
		NameType m_name;
		AgeType m_age;
};
 
//3.整个类模板化
template<typename T1>
void printPerson3(T1 &p)
{
	p.showPerson();
}
void test03()
{
	Person<string,int>p("ironMan",30);
	printPerson3(p);
 } 
int main() 
{
	test03();
	system("pause");
	return 0;
}

二、类模板继承

模板类的继承包括四种:

1.(普通类继承模板类)

1 template<class T>
2 class TBase{
3     T data;
4 ……
5 };
6 class Derived:public TBase<int>{
7 ……
8 };

2.(模板类继承了普通类(非常常见))

1 class TBase{
2 ……
3 };
4 template<class T>
5 class TDerived:public TBase{
6 T data;
7 ……
8 };

3.(类模板继承类模板)

 1 template<class T>
 2 class TBase{
 3 T data1;
 4 ……
 5 };
 6 template<class T1,class T2>
 7 class TDerived:public TBase<T1>{
 8 T2 data2;
 9 ……
10 };

4.(模板类继承类模板,即继承模板参数给出的基类)

1 #include<iostream>
 2 using namespace std;
 3 
 4 class BaseA{
 5 public:
 6     BaseA(){cout<<"BaseA founed"<<endl;}
 7 };
 8 class BaseB{
 9 public:
10     BaseB(){cout<<"BaseB founed"<<endl;}
11 };
12 template<typename T, int rows>
13 class BaseC{
14 private:
15     T data;
16 public:
17     BaseC():data(rows){
18         cout<<"BaseC founed "<< data << endl;}
19 };
20 template<class T>
21 class Derived:public T{
22 public:
23     Derived():T(){cout<<"Derived founed"<<endl;}
24 };
25 
26 void main()
27 {
28     Derived<BaseA> x;// BaseA作为基类
29     Derived<BaseB> y;// BaseB作为基类
30     Derived<BaseC<int, 3> > z; // BaseC<int,3>作为基类
31 }

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


   在类模板中,函数的声明和定义都应该在h文件或者在mian的cpp中,在类中声明,在类外定义需要加上模板的类限定符
    案例:template <class T1,class T2>
              class myson :public person<T1, T2>
              {public:int display(T1 x);};
            //;类内声明 类外实现(模板类成员函数)
             template <class T1,class T2>
            int myson<T1, T2>::display(T1 x){}    
          }
    小秘密:一般情况下会把定义模板类的文件后缀修改成.hpp的形式。
   练习:实现一个通用的数组类 ( )
          第一点:他需要支持基本数据类型和自定义类型。t* parr,int size,int cap)  cap是容量,已经存了多少元素。如果存了6个则cap=6
           第二点:通用数组中的数据要放入堆内存(new),需要提供
           第三点:需要实现构造 析构 有参构造函数
           第四点:需要实现==运算符重载,下标运算符[]重载。
          第五点:提供两个函数,可以给数组进行为插和尾删除。

案例:

#include <iostream>
#include <string>

using namespace std;

//类模板中成员函数类外实现
template<class T1, class T2>
class Person {
public:
	//成员函数类内声明
	Person(T1 name, T2 age);
	void showPerson();

public:
	T1 m_Name;
	T2 m_Age;
};

//构造函数 类外实现
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>::showPerson() {
	cout << "姓名: " << this->m_Name << " 年龄:" << this->m_Age << endl;
}

void test01()
{
	Person<string, int> p("Jerry", 20);
	p.showPerson();
}

int main() {

	test01();

	system("pause");

	return 0;
}

四、 类模板的友元函数


       1.类外实现友元函数:
           先需要在类内声明函数,声明的时候需要加空模板列表,也就是函数名后<>
           其次需要在类外实现,但一定是类的定义前实现,在friend函数声明前需要有函数体。
           最后在定义完友元函数后,需要先声明模板类。
       2.类内实现模板类的友元函数,和普通友元函数实现一样。

案例:

/* program2 */
#include <iostream>
using std::cout;
using std::endl;

//template prototypes
template <typename T> void counts();
template <typename T> void report(T &);

//template class
template <typename TT>
class HasFriendTem
{
private:
    TT item;
    static int cnts;
public:
    HasFriendTem(const TT & i):item(i){cnts++;}
    ~HasFriendTem(){cnts--;}
    friend void counts<TT>();
    friend void report<>(HasFriendTem<TT> &);
};

template <typename TT>
int HasFriendTem<TT>::cnts=0;

//template friend functions definitions
template <typename T>
void counts()
{
    cout<<"template size:"<<sizeof(HasFriendTem<T>)<<";";
    cout<<"template counts():"<<HasFriendTem<T>::cnts<<endl;
}

template <typename T>
void report(T& hf)
{
    cout<<hf.item<<endl;
}

int main()
{
    counts<int>();
    HasFriendTem<int> hfi1(10);
    HasFriendTem<int> hfi2(20);
    HasFriendTem<double> hfdb(15.5);
    report(hfi1);//generate report(HasFriendTem<int> &)
    report(hfi2);
    report(hfdb);//generate report(HasFriendTem<double> &)
    cout<<"counts<int>() output:\n";
    counts<int>();
    cout<<"counts<double() output:\n";
    counts<double>();

    return 0;
}


      
       
    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值