Biblioteca padrão do C++

Origem: Wikipédia, a enciclopédia livre.

Em C++, a biblioteca padrão é uma coleção de classes, funções e variáveis escritas na própria linguagem para facilitar o desenvolvimento de aplicações. Também incorpora a biblioteca padrão do C, e todas suas funcionalidades estão declaradas no espaço de nomes std.

Visão geral[editar | editar código-fonte]

A biblioteca padrão do C++ fornece vários containers genéricos, funções que utilizam e manipulam tais containers, funções-objeto, cadeias de caracteres e streams genéricos, suporte para algumas facilidades da linguagem e funções de uso geral, como funções matemáticas.

Os containers genéricos são uma implementação de elementos conhecidos em estrutura de dados. Diferentes containers compartilham uma mesma interface, o acesso é o mesmo. A escolha do uso geralmente depende da eficiência em determinadas tarefas que o container deverá desempenhar, o que está relacionado com a implementação interna da classe. Por exemplo, alguns containers são mais eficientes em busca e menos eficientes em inserções.

Ela também incorpora a biblioteca padrão do C90. Desta forma, as biblioteca-padrão do C sofreram uma adequação para pertencerem também ao espaço de nomes std: retirou-se o sufixo .h dos nomes dos arquivos de cabeçalho, e adicionou-se o prefixo c para indicar que pertence à linguagem C.

Os algoritmos, containers e iteradores dessa biblioteca são baseados na STL, e por esse motivo esses dois termos são muitas vezes confundidos. O iterador é um conceito importante da STL, e, portanto, da biblioteca padrão. Ele permite que os algoritmos usem os containers de forma genérica.

Lista de cabeçalhos[editar | editar código-fonte]

Containers[editar | editar código-fonte]

  • <bitset> - manipulação de arranjo de bits, algo parecido com vector<bool> (que é uma construção não recomendada[1])
  • <deque> - manipulação de lista duplamente ligada
  • <list> - manipulação de lista simplesmente ligada
  • <map> - manipulação de conjunto associativo ordenado (associação: chave → valor)
  • <queue> - manipulação de lista FIFO
  • <set> - manipulação de conjunto (sem repetição de valores)
  • <stack> - manipulação de lista LIFO
  • <vector> - manipulação de arranjo

Uso geral[editar | editar código-fonte]

Cadeias de caracteres[editar | editar código-fonte]

Streams e entrada/saída[editar | editar código-fonte]

  • <fstream> - manipulação de fluxo de dados em arquivo
  • <ios> - declaração mais geral de fluxo de dados
  • <iostream> - manipulação de fluxo de dados padrão do sistema (entrada padrão, saída padrão e saída de erros padrão)
  • <iosfwd> - declaração dos fluxos de dados presentes na linguagem
  • <iomanip> - manipulação da apresentação e do processamento de fluxos de dados
  • <istream> - manipulação de entrada de dados
  • <ostream> - manipulação de saída de dados
  • <sstream> - manipulação de fluxo de dados em cadeias de caracteres
  • <streambuf> - manipulação de buffers de fluxo de dados

Funcionalidades numéricas[editar | editar código-fonte]

  • <complex> - manipulação de número complexo
  • <numeric> - operações com conjuntos numéricos
  • <valarray> - arranjo de valores mutáveis

Suporte à linguagem C++[editar | editar código-fonte]

  • <exception> - manipulação de exceção
  • <limits> - manipulação de limites numéricos dos tipos embutidos na linguagem
  • <new> - manipulação de alocação e desalocação de memória
  • <typeinfo> - auxílio para o RTTI do C++

Biblioteca padrão do C[editar | editar código-fonte]

  • <cassert> - adequação de <assert.h>
  • <cctype> - adequação de <ctype.h>
  • <cerrno> - adequação de <errno.h>
  • <cfloat> - adequação de <float.h>
  • <climits> - adequação de <limits.h>
  • <cmath> - adequação de <math.h>
  • <csetjmp> - adequação de <setjmp.h>
  • <csignal> - adequação de <signal.h>
  • <cstdlib> - adequação de <stdlib.h>
  • <cstddef> - adequação de <stddef.h>
  • <cstdarg> - adequação de <stdarg.h>
  • <ctime> - adequação de <time.h>
  • <cstdio> - adequação de <stdio.h>
  • <cstring> - adequação de <string.h>
  • <cwchar> - adequação de <wchar.h>
  • <cwctype> - adequação de <wctype.h>

Descrições detalhadas[editar | editar código-fonte]

<algorithm>[editar | editar código-fonte]

Este cabeçalho fornece diversos algoritmos genéricos úteis para busca, ordenação e transformação de containers (estruturas de dados), entre outros. Ele podem ser invocados para diferentes containers através da interface comum dos iteradores, e de operadores específicos que cada algoritmo requisita da estrutura de dado usada. Os algoritmos geralmente são especificados através da posição de começo e de fim da estrutura de dados, e o iterador no final da estrutura deve ser acessível a partir do iterador no começo da mesma estrutura através de seguidos incrementos no iterador. Alguns algoritmos requerem uma condição especial de entrada; por exemplo os algoritmos de busca binária, que requerem uma estrutura de dados já ordenada previamente. Notar entretanto que esse requerimento é implícito e não detectável em tempo de compilação, cabendo a responsalibilidade de atender aos requisitos ao desenvolvedor.

Pode-se classificar os algoritmos dessa biblioteca em dois grandes grupos, os que realizam mutação no containers e os que não realizam mutação.[2] Algoritmos de busca, comparação e contagem de elementos não realizam mutação, apenas lêem o container e retornam como saída referências para elementos da estrutura. Em contrapartida, algoritmos de ordenação, de cópia, de transformação e de adição ou remoção de elementos realizam mutação.

Para algoritmos que realizam mutação, existe o sufixo especial _copy, que indica que o algoritmo mantém intacto o container passado como parâmetro, retornando na saída um novo container que corresponde ao container original mais o processamento realizado. Para todos os algoritmos, mutáveis ou não, existe o sufixo especial _if, usado em algoritmos que envolvem comparação de elementos. Ele indica que uma função de comparação está sendo passada por parâmetro para o algoritmo, em favor da utilização dos operadores padrão de comparação fornecidos pelo tipo de dado do container.

<fstream>[editar | editar código-fonte]

std::fstream é um manipulador de fluxos de dados de arquivos de computador especializado para o tipo de dado nativo char. Ele permite ler e escrever em modo de texto (utiliza-se os operadores de deslocamento de bits, << e >>) ou binário (utiliza-se os métodos read e write para buffers de dado).

A biblioteca padrão também fornece classes para casos de uso de std::fstream somente para leitura (std::ifstream) ou somente para escrita (std::ofstream).

A implementação de std::fstream segue o padrão RAII. O gerenciamento do arquivo aberto (um recurso do sistema) é de responsabilidade da classe. Isso implica que ao inicializar std::fstream (através de informações como o nome do arquivo e o modo de abertura) o recurso é adquirido, e na destruição de std::fstream o recurso é liberado ao sistema automaticamente. Apesar da biblioteca padrão fornecer o método close para a liberação manual do arquivo ao sistema, o RAII permite que isso seja feito automaticamente quando a instância de std::fstream sai de escopo no programa.

<functional>[editar | editar código-fonte]

Este cabeçalho fornece suporte para funções-objeto, classes que encapsulam funções de forma que a instância da classe possa ser invocada tal qual uma função qualquer. Por exemplo, as funções-objeto são usadas na STL para a passagem de predicados aos algoritmos genéricos de <algorithm>. São disponibilizadas funções-objeto unárias (que demandam um argumento) e binárias (que demandam dois argumentos), adaptadores que permitem converter ponteiros de funções em funções-objeto e adaptadores que permitem converter funções-objeto binárias em unárias ao associar um valor a um dos argumentos.

O cabeçalho ainda define algumas funções-objeto de uso geral tais como operações aritméticas e lógicas. Um exemplo é equal_to, uma função-objeto binária que testa se dois valores são iguais. Nada mais é que uma função de comparação genérica encapsulada em uma classe.

<iostream>[editar | editar código-fonte]

Este cabeçalho é responsável pela manipulação de fluxo de dados padrão do sistema (entrada padrão, saída padrão e saída de erros padrão) e representa uma evolução do cabeçalho <stdio.h> da linguagem C. São apresentados os objetos cin, cout, cerr e clog para o envio e recebimento de dados dos fluxos de entrada, saída, erro sem buffer e erro com buffer, respectivamente; para isso usa-se os operadores de deslocamento de bits (<< e >>).

Também são fornecidos métodos para a formatação do fluxo de dados, como width, que define uma largura para a saída, fill, que define um caractere específico para ser impresso caso o fluxo é menor que o mínimo esperado, e precision, que define a quantidade de dígitos significativos de números de ponto flutuante.

Alguns compiladores são incapazes de remover código desnecessário ao produzir executáveis que incluem esta biblioteca através de ligação estática. Por exemplo, um programa Olá Mundo usando-se a implementação GNU da biblioteca padrão produz um executável maior que o equivalente utilizando-se <cstdio>,[3] devido parcialmente a deficiências do ligador.[4]

<locale>[editar | editar código-fonte]

Este cabeçalho manipula diversas convenções culturais do utilizador, como a representação de números, moeda e datas, para efeitos de internacionalização. A biblioteca faz uso da faceta, uma interface para um serviço dum locale específico. Cada locale possui um conjunto de facetas. O construtor padrão da classe std::locale define uma cópia do locale da máquina executando o programa, com as convenções atuais do utilizador.

<map>[editar | editar código-fonte]

O container std::map<Key, Data, Compare, Alloc> é um conjunto associativo ordenado que mapeia um objetos do tipo Key (a chave) em objetos do tipo Data (o valor). As chaves são únicas: se um objeto é inserido com uma chave já existente, o valor presente é substituído pelo valor inserido.

O tempo requerido para acesso aleatório a cada elemento é , e os iteradores atribuídos não são invalidados após as operações de inserção e remoção. Portanto, a implementação mais usada para o container é a árvore de busca binária auto-balanceada (ainda que qualquer outra estrutura de dados que respeite as restrições de complexidade computacional pode ser usada, como uma skiplist).

Internamente, os elementos do mapa são ordenados através das chaves.

Uma variação do container é o std::multimap, que permite chaves repetidas.

<set>[editar | editar código-fonte]

O container std::set<Key, Compare, Alloc> é um conjunto associativo que permite acesso aleatório rápido aos dados. Difere do container std::map pois os valores dos elementos também são suas chaves. Por esse motivo, cada valor (e, portanto, sua chave) é único, não pode repetir. O container pode ser acessado de forma bidirecional, a partir do começo ou do fim.

A implementação interna do container geralmente é uma árvore de busca binária.[5]

Uma variação do container é o std::multiset, um multiconjunto associativo, que permite valores repetidos.

<sstream>[editar | editar código-fonte]

std::stringstream é um manipulador de fluxos de dados de cadeias de caracteres especializado para o tipo de dado nativo char. Ele permite ler e escrever em modo de texto (utiliza-se os operadores de deslocamento de bits, << e >>) ou binário (utiliza-se os métodos read e write para buffers de dado).

A biblioteca padrão também fornece classes para casos de uso de std::stringstream somente para leitura (std::istringstream) ou somente para escrita (std::ostringstream).

<string>[editar | editar código-fonte]

O container std::string é uma cadeia de caracteres especializada para o tipo de dado nativo char. Ele remove vários dos problemas introduzidos pela linguagem C ao confiar no programador no gerenciamento de cadeias de caractere, encapsulando internamente rotinas e considerações que o programador não precisa tomar conhecimento. Ele também permite conversão de e para cadeias de texto do C (const char*).

Diferente de uma cadeia de caracteres em C, que é um ponteiro para uma região de memória contendo a cadeia, o conteúdo de std::string é armazenada por valor. Por esse motivo, a operação de cópia possui tempo . Para evitar cópias desnecessárias, a passagem de cadeias de texto como parâmetro de funções é geralmente feita por referência constante. Isso possui uma segunda vantagem pois permite que a mesma função possa receber implicitamente uma cadeia de caracteres do C, sem a necessidade de sobrecarga para o tipo de dado const char*.

A especialização para cadeias de char nem sempre é desejada. Por exemplo, uma aplicação que implemente UTF-32 (o mapeamento do padrão Unicode para 32 bits, suficiente para representar todo o padrão) deve reservar quatro bytes para cada caractere, enquanto um char armazena somente um byte. Por isso, o conceito genérico de cadeia de texto é implementado no container std::basic_string, que pode ser especializado para qualquer tipo de dado.[6] No caso de UTF-32, pode-se usar uma especialização do container genérico para um tipo de dado que armazene pelo menos quatro bytes. Como na maioria das vezes um char é suficiente, a especialização é também definida no padrão por conveniência.

<vector>[editar | editar código-fonte]

O container std::vector é um arranjo e generaliza o conceito dum vector em C. Pode ser acessado através de índices para o elementos assim como em C (através de uma sobrecarga do operador adequado) e sua memória é alocada de forma contígua. Entretanto, diferente dum vetor em C, o tamanho do container é dinâmico com gerenciamento automático e há uma flexibilidade maior para adicionar elementos. Além de conhecer seu tamanho atual, uma instância de std::vector também conhece quantos elementos ainda pode alocar antes de precisar de redimensionamento: a alocação é feita em blocos e não para cada elemento, e é possível definir manualmente qual o tamanho do bloco. Diferente dum vetor em C, std::vector fornece o método at para acessar elementos pelo índice, mas com tratamento de exceções para o caso de índices inválidos (valores negativos ou acima do tamanho atual do container).

Para inserções no meio do container std::list é mais eficiente. Enquanto std::vector fornece inserção eficiente no final do container, std::deque fornece inserção eficiente tanto no começo quanto no final do container.[7] Além de inserção eficiente no final, pontos positivos do std::vector incluem acesso em tempo constante a qualquer elemento através do índice e iteração em tempo linear.[8]

Sendo um container genérico, pode ser especializado para diferentes tipos de dado. Entretanto, desaconselha-se especializá-lo para o tipo booleano nativo, bool,[1] cuja especialização já consta na biblioteca padrão.

Referências

  1. a b Herb Sutter (20 de outubro de 1999). «vector<bool>: More Problems, Better Solutions» (PDF). WG21 N1211 (em inglês). Gotw.ca. Consultado em 19 de agosto de 2007 
  2. «Algorithms» (em inglês). Rogue Wave Software. 1996. Consultado em 28 de outubro de 2007 
  3. «cbloatbloat» 
  4. «libstdc++-v3 FAQ, seção 2.5» 
  5. «set — C++ Reference». C++ Library Reference (em inglês). cplusplus.com - The C++ Resources Network. Consultado em 26 de junho de 2008 
  6. «Strings library — C++ Reference». C++ Library Reference (em inglês). cplusplus.com - The C++ Resources Network. Consultado em 26 de junho de 2008 
  7. «The vector Data Abstraction». Rogue Wave Software (em inglês). Roguewave.com. Consultado em 26 de fevereiro de 2008 
  8. «vector — C++ Reference». C++ Library Reference (em inglês). cplusplus.com - The C++ Resources Network. Consultado em 26 de junho de 2008 

Ver também[editar | editar código-fonte]