目录
1.类模板定义,类模板中的成员函数定义时,如果在外部定义,则需要加上类模板描述。
一.类模板
类模板通过实例化以后的对象被称为模板类
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();
}