Templates em C ++
C ++ é um exemplo de uma linguagem de programação com rigidez. É esta forte digitado-ness que permite que funções sejam sobrecarregadas, como mostrado no seguinte trecho de código:
vazio grau (Estudante) grau -void (Land) fn -void (Student s) {grau (s) -}
C ++ não tem problemas em entender que a chamada para notas) devem ser direcionadas para a função grau (Estudante).
Fortes métodos forças de digitação a ser sobrecarregado que aparecer o mesmo no nível C ++, mas são bastante diferentes na sua execução, como no exemplo a seguir:
int compare (l int, int r) {return (l> r)? 1: (l lt; r)? -1: 0-} int compare (l double, double r) {return (l> r)? 1: (l lt; r)? -1: 0-}
este comparar() retorna 1 se a esquerda; argumento lado é maior do que a direita; mão, -1 se o esquerdo; argumento lado é menor do que a direita; mão, e um 0 se forem iguais. Apesar da semelhança do código-fonte, o código de máquina gerada por estas duas funções é muito diferente, devido às diferenças na maneira que int é implementado contra duplo no nível da máquina.
O pré-processador oferece uma forma de evitar tais implementações redundantes:
#define COMPARAR (L, R) (((l)> (r)) 1:?? ((L) lt; (r)) -1: 0)
No entanto, esta sofre de uma série de limitações graves - não menos do que é a necessidade para a função para se encaixar em uma expressão (com efeito, sobre uma linha). Além disso, erros em uma macro pré-processador pode levar a problemas que são difíceis de depurar.
modelos de função
O recurso de modelo em C ++ permite ao programador para reter as vantagens de tipagem forte e evitar as limitações do pré-processador usando um marcador para o tipo. O seguinte define comparar() por alguma classe não especificada T para ser mais tarde denominado:
modeloT comparar (l T, T r) {return (l> r)? 1: (l lt; r)? -1: 0-}
Tal definição é conhecido como um modelo de função. Este modelo de função - cujo nome completo é comparar
template dupla comparar(Double, double) -
Você também pode permitir C ++ para encontrar e instanciar a classe T para você, quer fornecendo uma declaração parcial ou usando a função como mostrado no seguinte trecho de código de exemplo:
template dupla comparar (double, double) -int main () {cout lt; lt; Compare (0, 0) lt; lt; "" Lt; lt; comparar (1.0, 2.0) lt; lt; endl-retorno 0-}
Aqui a função comparar (double, double) é criada pela declaração inicial, mesmo sem o extra após o nome da função. A função comparar (int, int) é criado quando é usado na instrução Compare (0, 0).
modelos de classe
recurso de modelo do C ++ permite que as classes a serem definidos usando tipos que são especificadas mais tarde. Isto resolve uma série de problemas diferentes em uma maneira de tipo seguro. Um problema, embora longe de ser o único problema, é que de recipientes genéricos. (UMA recipiente é uma classe que contém objetos de outra classe.)
Nos primeiros dias de C ++, a única maneira de criar uma classe contêiner genérico era de contar com o genérico vazio ponteiro (o ponteiro de classe vazio*). Muito parecido com o #definir "Função" mencionado anteriormente, esta abordagem efetivamente evitou mecanismo de tipagem forte do C ++ com declarações como a seguinte:
classe Container {public: void add (void *) - void * get () - // ... outros membros ...} - Classe storeStudent container-void (Student s) {container.add ((void *) s) -} Student * getStudent () {return (Student *) container.get () -}
modelos C ++ permitir que o programador para definir um modelo de classe em que um ou mais tipos não for especificado até que a classe é usado:
modeloclasse Container {public: put void (T * p) -T * get () -} -
Na prática, o modelo de classe deve primeiro ser convertido em uma classe real, fornecendo um tipo de T. Nesse caso, pode ser utilizado em segurança de tipo completo:
Recipientecontainer-Student s-container.put (s) -Student * pS = container.get () -
Não há necessidade de definir o seu próprio recipiente de aula da Standard Template Library fornece uma série de tais classes. Por exemplo, o seguinte trecho de código cria uma lista ligada de ponteiros para Aluna objetos e soma uma unidade ao fim da lista de:
// Deve # includeno início do modulelist sList-Student * pS = new Student () - sList.push_back (s) -
Muitas das classes que você usa todos os dias são, na verdade, instanciações de modelos de classe. O exemplo mais comum é quando istream e ostream são usadas para a entrada e saída padrão.
Iterators
Embora eles não são diretamente parte do recurso de template, iterators fornecer uma maneira padrão para acessar os diferentes tipos de recipientes disponíveis no Standard Template Library. Todos os recipientes de proporcionar um método que retorna uma iteração para o início do recipiente e uma forma de verificar quando a iteração está na extremidade do recipiente (isto inclui recipientes não ordenados para que "começo" e "fim" é um conceito aleatório). O iterador próprio fornece pelo menos dois métodos: um para retornar o objeto atual e um para evitar o iterador para o próximo objeto.
Os código a seguir percorre uma coleção de ponteiros para Aluna objectos. Este mesmo código funciona independentemente de qual um dos muitos tipos de recipientes que você escolher para usar:
// displayAllStudents - percorrer uma lista de // estudantes- invocar o toString () // método em displayAllStudents eachvoid (lista sList) {for (auto iter = sList.begin (!) - iter = sList.end () - iter ++) {Student * pS = * iter-cout lt; lt; pS-> toString () lt; lt; }} endl-
(Este exemplo assume que a classe Aluna inclui um método para sequenciar() que retorna uma representação de caracteres de um estudante.)
Esta função utiliza o início() método para retornar um iterador que aponta para o primeiro membro do recipiente. A função percorre o recipiente até o iterador aponta para fim() que se refere ao membro após o último membro no recipiente. O operador de incremento move o iterador para o próximo membro no recipiente enquanto o operador * retorna o objeto apontado para pelo iterador.
o auto palavra-chave diz declarar iter ser do tipo retornado pela sList.begin (). Esta é uma extensão do C ++ adicionado pela norma 2011. Sem auto, Eu teria declarado iter ser do tipo Lista::const_iterator.