模板

Posted 7777lcc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板相关的知识,希望对你有一定的参考价值。

6-1 有序数组(类模板)
单位 福州大学

实现一个类模板,它可以接受一组数据,能对数据排序,也能输出数组的内容。

每行输入的第一个数字为0,1,2或3:为0时表示输入结束; 为1时表示将输入整数,为2时表示将输入有一位小数的浮点数,为3时表示输入字符。

如果第一个数字非0,则接下来将输入一个正整数,表示即将输入的数据的数量。

从每行第三个输入开始,依次输入指定类型的数据。

类模板:

template <class T>

class MyArray

裁判测试程序样例:

 
#include <iostream>
using namespace std;

/* 请在这里填写答案 */

template<class T>
MyArray<T>::~MyArray() delete[] data;

template<class T>
bool MyArray<T>::check()
    int i;
    for(i=0;i<size-1;i++)
        if(data[i]>data[i+1])  cout<<"ERROR!"<<endl;return false;
    return true;

int main( )

    MyArray<int> *pI;
    MyArray<float> *pF;
    MyArray<char> *pC;
    int ty, size;
    cin>>ty;
    while(ty>0)
        cin>>size;
        switch(ty)
            case 1: pI = new MyArray<int>(size);   pI->sort(); pI->check(); pI->display(); delete pI; break;
            case 2: pF = new MyArray<float>(size); pF->sort(); pF->check(); pF->display(); delete pF; break;
            case 3: pC = new MyArray<char>(size);  pC->sort(); pC->check(); pC->display(); delete pC; break;
        
        cin>>ty;
    
    return 0;


输入样例:
1 3 2 3 1
2 4 1.5 2.6 3.7 0.5
3 2 A a
0

输出样例:


1 2 3
0.5 1.5 2.6 3.7
A a

代码

template<class T>
class MyArray
private:
T *data;
int size;

public:
MyArray(int s);
~MyArray();
void sort();
void display();
bool check();
;

template<class T>
MyArray<T>::MyArray(int s)
size = s;
data = new T[size];
for(int i=0;i<size;i++)
cin>>data[i];


template<class T>
void MyArray<T>::display()
for(int i=0;i<size;i++)
cout<<data[i];
if(i<size-1)
cout<<" ";

cout<<endl;


template<class T>
void MyArray<T>::sort()
for(int i=0;i<size-1;i++)
for(int j=0;j<size-i-1;j++)
if(data[j]>data[j+1])
T temp = data[j];
data[j] = data[j+1];
data[j+1] = temp;

 

 

 

 

模板初步——定义模板

一、关键点

定义函数模板&类模板

模板参数列表:非类型参数

类模板类名的使用:依据作用域是否加上模板类型

类模板和友元:设置友好关系

模板参数:使用类的类型成员、默认模板实参

成员模板的使用:非模板类的成员模板、模板类的成员模板

 

二、定义函数模板

//模板参数T是一个类型 
template <typename T>
bool cmp(const T &a, const T &b)
{
	return a < b;
} 
//模板参数N是一个非类型参数 
template <unsigned N>
void get_val(int (&arr)[N])
{
	for (const auto &v : arr)
		cout << v << " ";
}

注:一个非类型参数可以一个整型,或者是一个指向对象或函数类型的指针或(左值)引用。

注:绑定到非类型整型参数的实参必须是一个常量表达式(从而允许编译器在编译时实例化模板)。

 

三、定义类模板

template <typename T>
class Blob
{
public:
	using size_type = typename vector<T>::size_type;
	//...
} 

int main()
{	
	Blob<int> b;
    return 0;
}

  

四、类模板的成员函数

template <typename T>
class Blob
{
public:
	using size_type = typename vector<T>::size_type;
	//...
private:
	void check(size_type i, const string &s) const;
};
//成员函数类外定义
template <typename T>
void Blob<T>::check(size_type i, const string &msg) const
{
	//...
}

注:定义在类模板内的成员函数被隐式声明为内联函数。

注:一个类模板的成员函数只有在使用时才被实例化。

 

五、类模板的友元

友元是模板:类可以授权给所有友元模板实例,也可以只授权给特定实例

友元不是模板:友元被授权可以访问所有模板实例

1. 一对一友好关系(友元是模板,且友元的模板类型与类模板的一致)

//Blob的友元是模板函数operator==和模板类BlobPtr 
template <typename> class Blob;	//该声明是operator==函数的参数声明所需要的 
template <typename T> bool operator==(const Blob<T>&, const Blob<T>&);
template <typename> class BlobPtr;	//该声明是Blob中的友元声明所需要的 

template <typename T>
class Blob
{
	//每个Blob实例将访问权限授予用相同类型实例化的BlobPtr和相等运算符 
	friend class BlobPtr<T>;
	friend bool operator==(const Blob<T>&, const Blob<T>&);
	//...
};
template <typename T> class pal;
template <typename T> class C { //C的每个实例将相同实例化的pal声明为友元 friend class pal<T>; }
template <typename T> class pal;

class C {
	//用类C实例化的pal是C的一个友元 
	friend class pal<C>;
}

2. 通用和特定的模板友好关系

template <typename T> 
class C {
	//pal的所有实例都是C的每个实例的友元 
	template <typename X> friend class pal;
}

 

class C {
	//pal的所有实例都是C的友元 
	template <typename X> friend class pal;
}
template <typename T> 
class C {
	//pal是C所有实例的友元 
	friend class pal;   //非模板类
}

注:可以将模板类型参数声明为友元

 

六、模板参数

1. 使用类的类型成员

T::value_type * p;

上面这句代码的默认含义是T类型的名为value_type的static数据成员与名为p的变量相乘。

为了显式声明value_type是一个模板类型参数的类型成员,我们可以如下定义:

typename T::value_type * p;

2. 默认模板实参

与函数默认实参一样,对于一个模板参数,只有当它右侧的所有参数都有默认实参时,它才可以有默认实参。

如果一个类模板为其所有模板参数都提供了默认实参,且我们希望使用这些默认实参,那就要:

template <class T = int> 
class C {
	//...
}; 
C<> c1;		//空<>表示我们希望使用默认实参 
C<double> c2;

 

七、成员模板

成员模板:本身是模板的成员函数,它不能是虚函数

1. 模板类的成员模板

template <typename T> 
class Blob {
	template <typename It> 		//此构造函数有自己的模板类型参数It 
	Blob(It b, It e);
	//...
}

template <typename T>
template <typename It>
Blob<T>::Blob(It b, It e) :data(make_shared<vector<T>>(b, e))
{
}

2. 非模板类的成员模板

与正常的函数模板没有区别,只不过作用域是在类内

 

 

 

 

以上是关于模板的主要内容,如果未能解决你的问题,请参考以下文章

C++模板编程入门模板介绍模板定义函数模板类模板模板的继承

类模板三种类模板参数

《c++从0到99》 六 模板

《c++从0到99》 六 模板

《c++从0到99》 六 模板

C++入门C++ 函数模板&类模板