C++ 学习总结(二十一)——类模板与模板类的特点,类模板的继承方式以及的继承特点

一.类模板

类模板通过实例化以后的对象被称为模板类

1.类模板定义,类模板中的成员函数定义时,如果在外部定义,则需要加上类模板描述。

#include<iostream>
#include<vector>
using namespace std;
//函数模板
template<typename T>
T add(T a, T b)
{
	return a + b;
}
//类模板
template<class T>
class com
{
public:
	T a;
	T b;
	T add()
	{
		cout << typeid(T).name() << endl;
		return a + b;
	}
};

void main2()
{
	com<int> c1;
	c1.a = 10;
	c1.b = 20;
	cout << c1.add() << endl;
	com<double> ff;

	vector<int> my;//本质为类模板
	my.push_back(10);


	cin.get();
}
void main1()
{
	int sum;
	float ff;
	sum=add<int>(1,2);
	ff = add<double>(1.1, 2.0);
	cout <<sum <<endl;
	cout << add(1.1, 2.2) << endl;
	cout << add(1, 2) << endl;

	cin.get();
}

2.通过类模板实现简单的array容器(容器的概念将在后面介绍,静态数组,定义时指定类型)

#pragma once
#include<iostream>
template<class T>
//参数默认情况 
//template<class T=int>	 myarray<> my;
class myarry
{
public:
	myarry();
	~myarry();
};

#include<iostream>
#include "myarry.h"
#include<array>
#include<string>
using namespace std;
template<class T>
myarry<T>::myarry()
{
	cout << "构造" << typeid(T).name() << endl;
}

template<class T>
myarry<T>::~myarry()
{
}
void main()
{
	myarry<int> my1;
}
void main5()
{
	array<string,2> strarry = {"calc","notepad"};
	for (auto i : strarry)
	{
		cout << i.c_str() << endl;
	}

	cin.get();
}

3.类模板包含多个类型

#include<iostream>
#include<string>
using namespace std;
template<class T1,class T2>
class myclass
{
public:
	T1 a;
	T2 b;
	myclass(T1 c,T2 d):a(c),b(d)
	{

	}
	void print()
	{
		cout << a << ' '<< b << endl;
	}
};
void main3()
{
	myclass<int,double> my(10,20.8);
	my.print();
	myclass<int, string> my1(10, "123456789");
	my1.print();
	cin.get();
}

4.通过类模板实现Array数组

类模板作为函数参数时,函数的形参可以是类模板或者类模板的引用,对应的实参是该类模板实例化的模板类对象

#pragma once
template<class T,int n> //包含多个参数的类模板
class Array
{
public:
	Array();
	//Array(int len);
	~Array();
	int size();//获得数组长度
	T get(int num);//获取对应位置数组值
	void set(T data, int num);//修改数组值
	T& operator [](int num);//重载方括号 
        void print(Array<T, n> &myarray);
public:
	T *p;
	//int n;
};
//类模板的实体
#include "Array.h"
#include<iostream>
#include<string>
using namespace std;
//template<class T,int n>
//Array<T,n>::Array()
//{
//	this->p = nullptr;
//	//this->n = 0;
//	 
//}
template<class T,int n>//类模板参数列表
Array<T,n>::Array()
{
	this->p = new T[n];
	//this->n = len;
}

template<class T,int n>
Array<T,n>::~Array()
{
	delete[] this->p;
	//this->n = 0;
}
template<class T, int n>
int  Array<T,n>::size()
{
	return n;//this->n ;
}
template<class T, int n>
T Array<T,n>::get(int num)
{
	if (num >= n || num < 0)
	{
		// 异常
		T *p(nullptr);
	}
	else
	{
		return this->p[num];//*(p+num)
	}
}
template<class T, int n>
void Array<T,n>::set(T data,int num)
{
	if (num >= n || num < 0)
	{
		// 异常
		T *p(nullptr);
	}
	else
	{
		this->p[num] = data;;//*(p+num)
	}
}

template<class T, int n>
T&  Array<T, n>::operator [](int num)
{
		  if (num >= n || num < 0)
		  {
			  // 异常
			  T *p(nullptr);
		  }
		  else
		  {
			 return this->p[num];//*(p+num)
		  }
}

template<class T,int n>
void print(Array<T,n> &myarray)//类模板的引用作为函数的参数
{
	for (int i = 0;i < myarray.size();i++)
	{
		myarray.set("hi", i);
		//cout << myarray.get(i) << endl;
		cout << myarray[i] << endl;
	}
}

void main()
{
	Array<string, 5> myarray;
	print(myarray);
	cin.get();
}
void main1()
{
	Array<string,5> myarray;
	for (int i = 0;i < myarray.size();i++)
	{
		myarray.set("hi", i);
		//cout << myarray.get(i) << endl;
		cout << myarray[i]<< endl;
	}


	cin.get();

}

二.类模板的继承,在类层次中的特点

类模板在进行继承时必须明确类型

1.类模板可以从模板类派生。

2.模板类也可以从非模板类派生。

3.非模板类从模板类派生,模板类需要实例化,传递类型。

4.模板类可以包含虚函数。

#include<iostream>
#include<string>
using namespace std;
class A
{
public: 
	//virtual void print() final //拒绝重载
	 void print()	                        //override 必须重载
	{
		cout << "A\n";
	}
	 virtual void run()
	 {

	 }
};
class B:public A
{
public:
	void run() override//用override修饰的成员函数不能修改函数名
	{

	}
	void print()
	{
		cout << "B\n";
	}
};
//模板类的继承
template<class T>
class C 
{
public:
	T x;
	C(T t) :x(t)
	{

	}
	void print()
	{
		cout << x<<"\n";
	}
	virtual void run() //声明虚函数,优先调用派生类的成员函数
	{
		cout << x << "\n";
	}		 
	virtual void go() = 0; // 纯虚函数,模板抽象类
};
template<class T>
class D :public C<T>
{
public:
	T y;
	D(T t1, T t2) :C(t1), y(t2)
	{

	}
	void print()
	{
		cout <<x<<' '<< y<<"\n";
	}
	void run()
	{
		cout << x << ' ' << y << "\n";
	}
	void go()
	{

	}
};
void main()//模板类包含虚函数
{
	D<string> dd("aaa","ggggg");
	C<int> *p = new D<int>(1,2);
	p->run();//调用派生类的成员函数
	cin.get();

}
void main2()
{
	D<string> d1("hello", "world");
	d1.print();
	cin.get();
}
void main1()
{
	B b1;
	b1.print();
	cin.get();

}
//从非模板类派生
class xyz
{
public:
	int x;
	int y;
	int z;
	xyz()
	{
		x = y = z = 0;
	}
	void print()
	{
		cout << x << ' ' << y << ' ' << z << endl;
	}
};
template<class T>
class E :public xyz
{
public:
	T a;
	E(T t1) :a(t1)
	{

	}
	void print()
	{
		cout << "a=" <<a<< endl;
		cout << x << ' ' << y << ' ' << z << endl;
	}
};
//非模板类从模板类派生
class F :public E<int> //传递类型
{
public:
	int ff=0;
	F(int a, int b) :E<int>(a), ff(b)
	{

	}
	void print()
	{
		cout << ff << endl;
		cout << "a=" << a << endl;
		cout << x << ' ' << y << ' ' << z << endl;
	}
};
void main4()
{
	F f(1,2);
	f.print();


	cin.get();
}
void main3()
{
	E<string> e1("hahahhaha");
	e1.print();
	cin.get();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值