欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

类模板(泛型编程)

程序员文章站 2022-05-13 19:10:46
...

泛型编程:(方法一致,但数据类型不确定)由函数模板或者类模板来完成的。
函数模板
  template<typename T>
  函数定义;

类模板:定义相同的操作,拥有不同数据类型的成员属性。
template<typename T>
class 类名
{
//属性
    确定类型
    泛型
};  


类模板继承
template<typename T>
class parent
{
};
//注意:
   1、如果子类不是类模板,则父类必须声明类模板的数据类型
   2、子类必须初始化父类(父类的构造器)
   3、如果子类模板,要么指定父类的类型,要么用子类的泛型来指定父类。
      在子类中初始化父类部分时,由构造器来构造器。调用构造器需要指定类型。
clas child:<继承方式> parent<类型>
{
    ...
        child():parent<类型>(..)
    ...
};

1、类模板实例化
    类<类型> 对象;

2、类外定义函数:
    template<typename T>
    类名<T>::方法(...)
    {
    }    
3、二次编译:见代码Complex.cpp代码(重载输出运算符)
    解决:前置声明。先在类定义的上面声明该函数为模板函数。    
        1、类的前置声明(类模板)
            template<typename T>
            class 类名;
        2、友元函数(模板函数)的前置声明
            template<typename T>
            函数声明;
        3、声明友元函数时,增加泛型支持。
        friend ostream& operator<< <T>(ostream& d2,Complex<T> &);

    

    类模板的使用 .

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

class people
{
public:
	//无参构造
	people(){}
	people(const char* n,char s):name(n),sex(s)
	{
	}
	friend ostream& operator<<(ostream&,people&);
protected:
	string name;//姓名
	char sex;
};
//重载运算符--友元函数
ostream& operator<<(ostream& output,people& p)
{
	output<<p.name<<" "<<p.sex<<" ";
	return output;
}

//定义数组类--泛型编程(类模板)
template <typename T>
class Array
{
public:
	//构造器
	Array(T b[],int ilen)//局部变量优先
	{
		this->ilen=ilen;
		memcpy(this->buf,b,ilen*sizeof(T));//内存拷贝
	}
	void show()
	{
		int i=0;
		while(i<this->ilen)
		{
			//基本类型,如果是复杂类型则重载
			cout<<this->buf[i++]<<" ";
		}
		cout<<endl;
	}
private:
	int ilen;//长度(整型)
	T buf[100];//泛型
};
//类继承:从父类派生出子类(拷贝父类一份给子类)

int main()
{
/******************基本类型************************/
//实例化--整型
	int buf[10]={1,2,3,4,5};
	Array<int> a(buf,5);
	a.show();
//浮点型
	float buf1[10]={3.14,7.0,8.9};
	Array<float> b(buf1,3);
	b.show();	

//复杂类型
	people buf2[3]={people("lifei,",'m'),people("lj",'m'),people("zzs",'w')};
	Array<people> c(buf2,3);		//Array(people* ,int)
	//构造器
	c.show();
}

   在复杂类型的时候  T buf[100];  的时候 , 因为此时的 T 是复杂类型  相当于==>  people  buf[100] ; 所以此时的 T buf[100] ; 会调用到 people 的无参构造 , 所以切记要为people 添加一个无参构造 , 在输出show的时候 , 因为是复杂类型 ,所以需要对输出运算符进行重载输出 , 不然会输出报错!

类模板(泛型编程)

 

      子类继承父类模板的使用 :    

子类继承父类的模板类 , 子类需要为继承的父类添加类型 , 可以自己定义类型 , 也可以定义子类的泛型 .

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

//类模板:
template<typename T>
class people
{
public:
	//有参构造:如果有参被定义,则无参构造不会被生成
	people(){}
	people(T i):id(i){}
protected:
	T id;
};

//子类:是类型模板
template<typename T1>
class worker:public people<T1>//people要么自己指定类型,要么用子类的泛型
{
public:	
	//无参
	worker():people<T1>()
	{
	}
	worker(T1 id,T1 g,int s):people<T1>(id)
	{
		this->g=g;
		this->score=s;
	}
	void show()
	{
		cout<<g<<" "<<score<<" "<<id<<endl;
	}
protected:
	T1 g;
	int score;
};

/*
//继承:子类不是类模板
class worker:public people<int>
{
public:
	//
	worker():people()
	{
		
	}	
	worker(int i,const char* n):people(i),name(n)
	{
	}
	void show()
	{
		cout<<"ID:"<<this->id<<" "<<this->name<<endl;
	}
protected:
	string name;	
};
*/
int main()
{
/*
//实例化:
	people<int> a;

	worker w(1001,"llllllll");
	w.show();
*/
	worker<int> w(1001,4,100);
	w.show();
	return 0;
}

 

   类外实现方法的定义 : 

#include<iostream>
using namespace std;

//前置声明:告诉编译器此函数为模板函数
template<typename T>
class Complex;//声明类

template<typename T>
ostream& operator<<(ostream&,Complex<T> &);

//类模板
template<typename T>
class Complex
{
public:
	Complex(T d1,T d2);
	//友元
	friend ostream& operator<<<T>(ostream&,Complex<T> &);
protected:
	T a;
	T b;
};
//类外实现方法的定义
template<typename T>
Complex<T>::Complex(T d1,T d2):a(d1),b(d2)
{
}

//重载输出  Complex是泛型    函数模板
template<typename T1>
ostream& operator<<(ostream& output,Complex<T1> &c)
{
	output<<c.a<<" "<<c.b<<" ";
}
int main()
{
	//实例化
	Complex<float> c(1,2);
	cout<<c<<endl;

	return 0;
}

 

 

相关标签: 原创