[Conhecimento básico de C ++] Programação genérica - modelo

Programação genérica

Primeiro pense em uma questão: como implementar uma função de troca universal?

Muitas pessoas aqui podem pensar em sobrecarga de função. Sim, a sobrecarga de função pode realizar a troca de diferentes tipos de dados, mas também tem grandes falhas:

  1. Funções sobrecarregadas são diferentes apenas em tipos, e a taxa de reutilização de código é relativamente baixa. Enquanto novos tipos aparecem, as funções correspondentes precisam ser adicionadas
  2. A capacidade de manutenção do código é relativamente baixa e um erro pode fazer com que todas as sobrecargas dêem errado

Você pode fornecer um modelo ao compilador e permitir que ele use o modelo para gerar código de acordo com diferentes tipos?

O conceito de
programação genérica será impresso aqui : Programação genérica: Escrever código genérico que não tem nada a ver com tipos é um meio de reutilização de código. Os modelos são a base da programação genérica.

Template de função

conceito:

O template de função representa uma família de funções. O template de função não tem nenhuma relação com o tipo. Ele é parametrizado quando usado, e uma versão de tipo específico da função é gerada de acordo com o tipo do parâmetro atual.

Formato de modelo de função

template <nome do tipo T1,
nome do tipo T2,…, nome do tipo Tn> nome da função do tipo de valor de retorno (lista de parâmetros) {}

template<typename T>
void Swap( T& left, T& right) {
    
    
 T temp = left;
 left = right;
 right = temp; }
//注意:typename是用来定义模板参数的关键字
//也可以使用class(切记:不能使用struct)

No estágio de compilação do compilador, para o uso de funções de modelo, o compilador precisa deduzir e gerar o tipo de função correspondente para chamada com base no tipo do parâmetro real passado.
Por exemplo: ao usar um modelo de função com o tipo duplo, o compilador determina T como o tipo duplo deduzindo o tipo do parâmetro real e, em seguida, gera um código que trata do tipo duplo, e o mesmo é verdadeiro para o caractere tipo.

Instanciação de modelos de função

  1. Instanciação implícita: deixe o compilador deduzir o tipo real do parâmetro do modelo com base no parâmetro real
template<class T> T Add(const T& left, const T& right) 
{
    
    
 	return left + right; 
}
int main()
{
    
    
 	int a1 = 10, a2 = 20;
 	double d1 = 10.0, d2 = 20.0;
	Add(a1, a2);
 	Add(d1, d2);
 
 /*
 该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型
 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,
 编译器无法确定此处到底该将T确定为int 或者 double类型而报错
 注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
 Add(a1, d1);
 */
 
 // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
 	Add(a, (int)d);
 	return 0; 
 }
  1. Instanciação explícita: especifique o tipo real do parâmetro do modelo no <> após o nome da função
int main(void) 
{
    
    
 	int a = 10;
 	double b = 20.0;
 
 	// 显式实例化
 	Add<int>(a, b);
 	return 0; 
 }

Se os tipos não corresponderem, o compilador tentará realizar a conversão implícita de tipo.Se a conversão falhar, o compilador relatará um erro.

Princípio de correspondência de parâmetros do modelo de função

  1. Uma função não modelo pode existir ao mesmo tempo que um modelo de função com o mesmo nome, e o modelo de função também pode ser instanciado como esta função não modelo
  2. Para uma função não modelo e um modelo de função com o mesmo nome, se outras condições forem iguais, a função não modelo será chamada primeiro e uma instância não será gerada a partir do modelo. Se o modelo pode produzir uma função com uma correspondência melhor, o modelo será selecionado
  3. As funções de modelo não permitem a conversão automática de tipo, mas as funções comuns podem realizar a conversão automática de tipo

Modelo de classe

Formato de definição do modelo de classe

template<class T1, class T2, ..., class Tn>
class 类模板名
{
    
    
 // 类内成员定义
};

Exemplo:

// 动态顺序表
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Vector
{
    
     
public :
 Vector(size_t capacity = 10)
 : _pData(new T[capacity])
 , _size(0)
 , _capacity(capacity)
 {
    
    }
 
 // 使用析构函数演示:在类中声明,在类外定义。
 ~Vector();
 
 void PushBack(const T& data)void PopBack()// ...
 
 size_t Size() {
    
    return _size;}
 
 T& operator[](size_t pos)
 {
    
    
 assert(pos < _size);
 return _pData[pos];
 }
 
private:
 T* _pData;
 size_t _size;
 size_t _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
    
    
 if(_pData)
 delete[] _pData;
 _size = _capacity = 0; }

Instanciação do modelo de classe

A instanciação do modelo de classe é diferente da instanciação do modelo de função. A instanciação do modelo de classe precisa seguir o nome do modelo de classe com <> e, em seguida, colocar o tipo instanciado em <>. O nome do modelo de classe não é a classe real, mas o instanciado O resultado é a classe real.

// Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;

Acho que você gosta

Origin blog.csdn.net/weixin_43962381/article/details/114990116
Recomendado
Clasificación