类模板(泛型编程)

版权声明:如需转载,请联系原作者授权... https://blog.csdn.net/Superman___007/article/details/82291676

泛型编程:(方法一致,但数据类型不确定)由函数模板或者类模板来完成的。
函数模板
  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的时候 , 因为是复杂类型 ,所以需要对输出运算符进行重载输出 , 不然会输出报错!

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

扫描二维码关注公众号,回复: 3158747 查看本文章

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

#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;
}

猜你喜欢

转载自blog.csdn.net/Superman___007/article/details/82291676