C++

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

C++

Paradigma: Abstração de dados,
Orientação a objeto,
Programação genérica,
Programação procedural
Surgido em: 1985
Última versão: ISO/IEC C++ 2003 (2003)
Criado por: Bjarne Stroustrup
Estilo de tipagem: Estática, fraca ou forte, insegura
Compiladores: C++ Builder, G++, MinGW, Microsoft Visual C++
Dialetos: ISO/IEC C++ 1998
ISO/IEC C++ 2003
Influenciada por: Ada 83, ALGOL 68, C, CLU, ML, Simula
Influenciou: Ada 95, C#, D, Java, PHP, Action Script
Licença: {{{licença}}}
Website: {{{website}}}

O C++ (em português lê-se "cê mais mais" ou /sê/ /máys/ /máys/, em inglês lê-se "cee plus plus" ou /si/ /plâs/ /plâs/) é uma linguagem de programação de alto nível com facilidades para o uso em baixo nível, multiparadigma e de uso geral. Desde os anos 1990 é uma das linguagens comerciais mais populares, sendo bastante usada também na academia por seu grande desempenho e base de utilizadores.

Bjarne Stroustrup desenvolveu o C++ (originalmente com o nome C with Classes, que significa C com classes em português) em 1983 no Bell Labs como um adicional à linguagem C. Novas características foram adicionadas com o tempo, como classes, funções virtuais, sobrecarga de operadores, herança múltipla, templates e tratamento de exceções. Após a padronização ISO realizada em 1998 e a posterior revisão realizada em 2003, uma nova versão do padrão da linguagem está em desenvolvimento. Conhecida informalmente como C++0x[1], seu lançamento está previsto para 2009, tornando-se então o padrão C++09[2].

Índice

[editar] História

[editar] A evolução da linguagem

O C++ foi inicialmente desenvolvido por Bjarne Stroustrup dos Bell Labs, durante a década de 1980 com o objectivo de melhorar a C ainda que mantendo máxima compatibilidade. Stroustrup percebeu que a linguagem Simula possuía características bastante úteis para o desenvolvimento de software, mas era muito lenta para uso prático. Por outro lado, a linguagem BCPL era rápida, mas possuía demasiado baixo nível, dificultando sua utilização em desenvolvimento de aplicações. Durante seu período na Bell Labs, ele enfrentou o problema de analisar o kernel UNIX com respeito à computação distribuída. A partir de sua experiência de doutorado, começou a acrescentar elementos do Simula no C. O C foi escolhido como base de desenvolvimento da nova linguagem pois possuía uma proposta de uso genérico, era rápido e também portável para diversas plataformas. Algumas outras linguagens que também serviram de inspiração para o cientista da computação foram ALGOL 68, Ada, CLU e ML.

Bjarne Stroustrup, idealizador da linguagem C++
Bjarne Stroustrup, idealizador da linguagem C++

Ainda em 1983 o nome da linguagem foi alterado de C with Classes para C++. Novas características foram adicionadas, como funções virtuais, sobrecarga de operadores e funções, referências, constantes, gerenciamento manual de memória, melhorias na verificação de tipo de dado e estilo de comentário de código de uma linha (//). Em 1985 foi lançada a primeira edição do livro The C++ Programming Language, contendo referências para a utilização da linguagem, já que ainda não era uma norma oficial. A primeira versão comercial foi lançada em outubro do mesmo ano[3]. Em 1989 a segunda versão foi lançada, contendo novas características como herança múltipla, classes abstratas, métodos estáticos, métodos constantes e membros protegidos, incrementando o suporte a orientação a objeto. Em 1990 foi lançado o livro The Annotated C++ Reference Manual, que tornou-se base para o futuro padrão. Outras adições na linguagem incluem templates, tratamento de exceções, espaço de nomes, conversão segura de tipo de dado e o tipo booleano.

Assim como a linguagem, sua biblioteca padrão também sofreu melhorias ao longo do tempo. Sua primeira adição foi a biblioteca de E/S, e posteriormente a Standard Template Library (STL); ambas tornaram-se algumas das principais funcionalidades que distanciaram a linguagem em relação a C. Criada primordialmente na HP por Alexander Stepanov[4] no início da década de 1990 para explorar os potenciais da programação genérica, a STL foi apresentada a um comitê unificado ANSI e ISO em 1993 à convite de Andrew Koenig. Após uma proposta formal na reunião do ano seguinte, a biblioteca recebe o aval do comitê.

Depois de anos de trabalho, o mesmo comitê ANSI/ISO padronizou o C++ em 1998 (ISO/IEC 14882:1998). Após alguns anos foram reportados defeitos e imprecisões no documento, e uma correção foi lançada em 2003[5].

Por muito tempo, o C++ foi encarado como um superconjunto do C (uma discussão sobre o tema encontra-se abaixo na seção de incompatibilidades). Entretanto, em 1999 o novo padrão ISO para a linguagem C tornou as duas linguagens ainda mais diferentes entre si. Devido a essas incompatibilidades, muitas empresas que desenvolvem compiladores não oferecem suporte à versão mais recente da linguagem C.

Pode-se dizer que C++ foi a única linguagem entre tantas outras que obteve sucesso como uma sucessora à linguagem C, inclusive servindo de inspiração para outras linguagens como Java, a IDL de CORBA e C#.

[editar] O nome C++

Durante sua fase inicial de desenvolvimento, a linguagem era chamada "novo C" ou ainda "C com classes". O termo "C++" é creditado a Rick Mascitti[6], e foi utilizado pela primeira vez em dezembro de 1983. Ele é uma referência ao operador de incremento ++, significando um acréscimo (uma evolução) à linguagem C. Em tom humorado, desenvolvedores software e especialistas em informática no início da década de 1990 costumavam relacionar o ++ do nome à grande insistência dos programadores em utilizar o C++ da mesma forma que a linguagem C, não usufruindo das novas facilidades que a linguagem poderia fornecer. Assim como o ++ estava sendo aplicado de maneira pós-fixa à letra C, a linguagem C++ era uma evolução do C pós-fixada, que só tornar-se-ia realidade em algum futuro remoto, não naquele momento.

[editar] Trabalhos futuros

A linguagem continua evoluindo de forma a fornecer novas funcionalidades. O grupo de desenvolvimento Boost.org trabalha para evoluir a biblioteca padrão, informando o comitê oficial da linguagem quais facilidades possuem maior retorno positivo dos usuários, seja por qualidade ou por utilidade, e quais ainda devem ser desenvolvidas. Tudo indica que o C++ continuará com sua natureza multiparadigma. Por exemplo, o trabalho da Boost.org dedica-se a acrescentar as qualidades da programação funcional e genérica. O padrão C++ não define a implementação para a definição de nomes e tratamento de exceções, entre outras facilidades específicas, o que freqüentemente torna incompatíveis códigos objeto produzidos por diferentes compiladores. Apesar disso, existem padrões periféricos específicos para certas plataformas ou sistemas operacionais para padronizar compiladores dessas plataformas, como por exemplo o C++ ABI[7].

As empresas de desenvolvimento de compiladores ainda se esforçam para suportar inteiramente o padrão, especialmente na área de templates. Uma das disputas se refere à palavra reservada export, que permite que a definição de um template seja separada de sua declaração. O primeiro compilador a implementar export foi o Comeau C++ em 2003 (cinco anos após o lançamento do padrão), e no ano seguinte uma versão beta do Borland C++ Builder X também suportava a facilidade. Interessante notar que ambos os compiladores são baseados na versão EDG do C++. Muitos livros fornecem exemplos de códigos para implementar export[8] que não são compiláveis, mas não há referências para o problema mencionado. Outros compiladores como o Microsoft Visual C++ e o GCC não suportam a facilidade. O secretário do comitê oficial do C++ Herb Sutter recomendou que a palavra fosse removida de versões futuras do padrão da linguagem[9], mas após discussão a decisão final foi mantê-la[10].

Outras disputas relativas a templates se referem à especialização parcial, que foi pouco suportada por muitos anos depois que o C++ padrão foi lançado.

Atualmente o comitê de padronização do C++ está trabalhando para estender a linguagem em uma nova especificação, conhecida informalmente por C++0x. Esse nome é uma referência ao ano no qual o padrão será lançado, possivelmente em 2009[11]. A maioria do trabalho foca grandes adições na biblioteca padrão e poucas na especificação da própria linguagem. Grande parte das inovações será derivada do trabalho desenvolvido pelo grupo Boost, que já provou o conceito de várias inovações em uma ampla base de utilizadores. Novas funcionalidades previstas para a biblioteca padrão incluem suporte à expressões regulares[12], suporte à tuplas[13], dedução de tipo de dado através da palavra reservada auto[14], suporte ao cálculo lambda[15][16], delegação de construtores[17] e a adição da palavra reservada finally para tratamento de exceções, entre outras.

No desenvolvimento do novo padrão o comitê aplicou algumas diretivas ao projeto. Deseja-se manter estabilidade e compatibilidade com a versão anterior do padrão, lançada em 1998, e possivelmente com C. Deseja-se também preferir a introdução de novas funcionalidades através da biblioteca padrão ao invés de estender a linguagem por si própria. Isso porque a linguagem é historicamente conhecida por evoluir de maneira bastante conservadora, em favor da continuação de uso de código legado. A adição de palavras reservadas é um grande fator de incompatibilidade com código antigo. A biblioteca padrão possui a vantagem de poder lidar com problemas de compatibilidade e concorrência de nomes através do uso de espaço de nomes (ver a seguir).

Outro desejo do comitê é facilitar o projeto de sistemas e bibliotecas ao invés de introduzir funcionalidades úteis somente à aplicações específicas (ou nichos de mercado), por ser uma linguagem de programação de propósito geral. Um dos itens relacionados à facilidade da linguagem está em tornar o C++ mais fácil de se aprender, sem remover utilitários entre especialistas. Parte desse propósito está direcionado na aplicação de "conceitos", um método que tornará os erros de compilação muito mais legíveis para o desenvolvedor. Para especialistas, a facilitação de uso do C++ será aumentada ao aumentar a segurança e consistência da linguagem.

[editar] Características

[editar] Filosofia

No livro In The Design and Evolution of C++ (1994), Bjarne Stroustrup descreve algumas regras que ele utiliza para desenvolver a linguagem, como exemplificado abaixo:

  • C++ é desenvolvido para ser uma linguagem tipada estaticamente e de proposta geral que é tão eficiente e portável quanto o C.
  • C++ é desenvolvido para suportar múltiplos paradigmas.
  • C++ é desenvolvido para fornecer ao programador escolhas, mesmo que seja possível ao programador escolher a opção errada.
  • C++ é desenvolvido para ser o quanto mais compatível com C possível, fornecendo transições simples para código C.
  • C++ evita fornecer facilidades que são específicas a certas plataformas ou a certos grupos de desenvolvedores.
  • C++ não exige overhead para facilidades que não são utilizadas.
  • C++ é desenvolvido para ser utilizado mesmo sem um ambiente de desenvolvimento sofisticado.

Stanley B. Lippman documenta em seu livro Inside the C++ Object Model (1996)[18] como compiladores convertem código de programas C++ em mapeamentos de memória. Lippman trabalhou implementando e mantendo o C-front, a implementação original do C++ nos Bell Labs.

Stroustrup sempre desejou que o C++ fosse mantido como uma linguagem de pequena especificação, apesar de pressões externas para adições de novas funcionalidades na especificação da própria linguagem ao invés da codificação de novas bibliotecas para a biblioteca padrão. Brian Kernighan notou que enquanto em C existe geralmente uma maneira de resolver problemas, em C++ existem várias. Na maioria das linguagens de programação, um padrão ou um conjunto bastante restrito de padrões de projeto de software é escolhido para o desenvolvimento. Entretanto, isso não acontece em C++, pois a escolha é delegada ao desenvolvedor. É um conceito que prega que não existe paradigma de programação ou padrão de desenvolvimento que resolva todos os problemas, por isso a pluralidade e generalidade de aplicações para a linguagem. Tal filosofia assusta iniciantes e professores, que sentem que a linguagem deveria ser de fácil aprendizado, algo que o C++ não é.

[editar] Biblioteca padrão

Ver artigo principal: Biblioteca padrão do C++
Ver artigo principal: Standard Template Library

A biblioteca padrão do C++ incorpora a biblioteca padrão do C com algumas pequenas modificações para trabalhar melhor com as novas funcionalidades criadas pela linguagem. Outra grande parte da biblioteca é composta pela biblioteca padrão de templates (STL). Ela fornece ferramentas úteis como containers (vetores, listas, entre outros), algoritmos (filtragem de elementos de container, busca, ordenação, entre outros) e iteradores (ponteiros inteligentes genéricos para acessar tais containers e interligá-los aos algoritmos). Usando templates é possível escrever algoritmos genéricos que funcionam para qualquer container ou sequência definida por iteradores. Tendo em vista que um iterador nada mais é que um ponteiro encapsulado, é possível também utilizar os algoritmos genéricos em vetores C, utilizando-se ponteiros comuns para tal. Como em C, os módulos da biblioteca são acessadas utilizando a diretiva #include; ao todo são fornecidos 69 cabeçalhos-padrão, dos quais 19 estão em depreciação.

Devido ao fato da biblioteca padrão ter sido desenvolvida por especialistas e de já ter sido amplamente utilizada comercialmente e academicamente, é recomendado utilizar seus componentes ao invés de componentes próprios. Por exemplo, utilizar std::vector e std::string ao invés de declarar vetores herdados do C não somente torna o desenvolvimento mais simples, como também traz mais segurança e escalabilidade para o sistema.

A biblioteca STL foi originalmente desenvolvida pela HP[4] e posteriormente pela SGI, antes de sua incorporação na biblioteca padrão do C++. O padrão não a define como "STL", mas ainda utiliza-se esse termo para distingui-la do resto da biblioteca. O projeto STLPort mantém uma implementação atualizada da biblioteca, e é baseado na SGI STL. O projeto Boost fornece elementos adicionais à STL, dos quais alguns já são considerados a serem parte da biblioteca padrão no futuro.

[editar] Operadores

Ver artigo principal: Operadores em C e C++

Os operadores em C++ são um conjunto de todos os operadores do C mais novas adições à linguagem. Um grupo de novos operadores do C++ são os relativos à conversão de tipo de dado, e consistem em const_cast, static_cast, dynamic_cast e reinterpret_cast. Eles são uma evolução a conversão de dados utilizada em C, que limitava-se a oferecer um método para conversão tal qual static_cast. dynamic_cast refere-se diretamente ao suporte de herança e polimorfismo oferecido pela linguagem, e está relacionado a outro novo operador, typeid, que retorna informações sobre o tipo de dado derivado pelo operando. Ambos os operadores requerem a habilitação de RTTI para funcionar. Outro grupo de novos operadores são os relativos à alocação de memória, e consistem em new e delete. Assemelham-se às funções malloc e free respectivamente, que estão presentes na biblioteca padrão do C. Outro novo operador é o de resolução de escopo, ::, e que refere-se diretamente ao suporte de espaço de nomes e orientação a objeto oferecido pela linguagem. Com ele é possível declarar e acessar espaços de nomes, e também declarar classes e acessar objetos.

O C++ define que alguns dos operadores podem ser sobrecarregados, o que permite, assim como na sobrecarga de funções, que diferentes tipos de dados sejam passados para um operador de forma a produzir diferentes resultados. Essa técnica também permite que classes definidas por utilizadores também possam usufruir de operadores próprios, tornando possível que uma classe Lista possa sobrecarregar o operador de apêndice += para que diversos elementos possam ser adicionados a lista, como elementos ou outras listas. Alguns operadores de classes definidas pelo utilizador devem ser obrigatoriamente sobrecarregados (definidos) a fim de poderem ser utilizados pela STL. Por exemplo, uma classe Funcionario deve fornecer o operador menor que (<) para ser utilizada pela função de ordenação (sort). De acordo com o padrão atual da linguagem, este requerimento é implícito durante a compilação: caso a função sort seja invocada para a um container da classe Funcionario e esta não define o operador <, há erro de compilação. Para padrões futuros planeja-se introduzir os "conceitos", que auxiliaram a programação genérica na especificação dos requerimentos de um tipo de dado para que ele seja usado em uma função. Por exemplo, os iteradores passados para sort estarão associados ao conceito "tipo de dado comparável", isto é, um tipo de dado que declara o operador <. Ao explicitar essa relação o código se torna mais consistente, e o compilador é auxiliado a fim de retornar uma mensagem de erro mais adequada ao utilizador caso haja problemas durante a compilação.

[editar] Pré-processador

Ver artigo principal: Pré-processador

O C++ é compilado em três fases: pré-processamento, compilação propriamente dita (tradução para código objeto) e ligação [19][20]. Durante a primeira fase, as diretivas de pré-processamento são aplicadas através de transformações léxicas no próprio código fonte, que então alimenta as próximas fases de compilação. Elas são identificadas no código através do caractere #. O pré-processamento é utilizado para substituir partes de código, para inutilizar partes de código e para importar módulos externos.

Por exemplo, o código #define PI 3.1415926535897932384626433 fará com que sempre que PI aparecer no código, este será substituido por 3.1415926535897932384626433. Outro uso do pré-processador é o que segue: #include <iostream> fará com que seja incluído (importado) todos o conteúdo da biblioteca iostream.

[editar] Templates

Os templates são diferentes de macros de programação (que também podem ser usadas em C++, um artifício herdado do C): enquanto ambas as facilidades podem ser utilizadas para produzir código em tempo de compilação, templates não restringem-se à substituições léxicas. Eles possuem conhecimento da semântica e do sistema de tipagem da linguagem, e são utilizados principalmente para polimorfismo estático (ver exemplo em anexo) e programação genérica. Um template também é uma máquina de Turing completa.

No campo de programação genérica, um tipo de dado parametrizado em C++ é chamado uma classe template. Ela define através de parâmetros como devem ser os tipos de dado internos utilizados ao instanciar o objeto. Dessa maneira é possível codificar uma classe genérica arranjo, que ao ser instanciada pode tornar-se um arranjo de números inteiros ou um arranjo de carros de corrida (desde que carro de corrida esteja definido no escopo da instancialização).

[editar] Objetos

Ver artigo principal: Orientação a objeto

O C++ introduziu alguns conceitos da orientação a objeto ao C, como exemplificado pelas classes, que apresentam quatro características comumente presentes em linguagens de programação orientadas a objeto: abstração, encapsulamento, herança e polimorfismo. Cada vez que uma classe é instanciada é criado um objeto na memória, que é basicamente um conjunto de atributos e operações reunidos.

[editar] Encapsulamento

Ver artigo principal: Encapsulamento

O encapsulamento permite que os atributos de classes possam ser declarados como públicos, privados ou protegidos. Um atributo público (o menos restrito) pode ser acessado a partir de qualquer método que tenha acesso ao objeto. Um atributo privado (o mais restrito) só pode ser acessado por métodos da própria classe e por métodos explicitamente declarados como permitidos para tal (utilizando a palavra reservada friend). Atributos protegidos só podem ser acessados por métodos da mesma classe, por métodos de classes herdadas e por métodos explicitamente declarados (utilizando a palavra reservada friend). É considerado como uma boa prática de programação restringir ao máximo o acesso aos atributos, de forma a isolar detalhes de implementação de uma classe, tornando públicas somente as funções membro que realizam uma interface mínima da classe com outros componentes.

O isolamento dos dados proposto pelo encapsulamento não é infalível, podendo ser contornado ao realizar operações de baixo nível em objetos. Dessa maneira, um atributo privado pode ser acessado e modificado a partir de um ponteiro para seu endereço de memória sem problemas, ainda que isso seja considerado uma má prática de programação. Tal característica, herdada da linguagem C, é reflexo direto da liberdade que o C++ fornece ao desenvolvedor em relação a padrões de projeto de software, cabendo a ele decidir qual é o mais adequado para seu algoritmo. O desenvolvedor tanto pode esquecer tal característica, atendo-se somente a detalhes de especificação em alto nível, quanto adequar tais características em sua especificação de forma mais baixo nível, visando desempenho ou algum outro objetivo.

[editar] Herança

Ver artigo principal: Herança

A herança de uma classe para com outra pode ser declarada como pública, protegida ou privada. Isso determina o quão relacionadas as classes serão entre si. Somente a herança pública corresponde ao conceito usual de herança, pois permite acesso total aos atributos da classe-base. Entretanto, pode-se também declarar heranças protegidas e privadas, com características parecidas como as detalhadas anteriormente sobre encapsulamento. Essa funcionalidade adicionou ao C++ a possibilidade de criação de classes abstratas, que não podem ser instanciadas, mas que oferecem interfaces de funcionamento para suas respectivas classes herdadas. Ela é um princípio básico da orientação a objeto para a reutilização de código, pois permite que classes (possivelmente escritas por outros desenvolvedores e então não modificáveis) possam ser herdadas de forma a ser incrementadas em funcionalidade.

A herança múltipla é uma das características do C++ mais controversas. Ela permite que uma classe possa ser derivada de mais de uma classe base, o que pode resultar em um complicado grafo de herança e relacionamento entre classes. Por exemplo, uma classe Gato voador pode ser derivada tanto das classes Gato quanto Mamífero voador. A mistura de heranças reflete em uma mistura de espaços de nomes na classe herdada, o que pode ser resolvido através da declaração local de espaço de nomes, como explicado adiante.

[editar] Polimorfismo

Ver artigo principal: Polimorfismo

C++ suporta diversos tipos de polimorfismos, sejam estáticos (resolvidos em tempo de compilação de código) ou dinâmicos (resolvidos em tempo de execução de código). A sobrecarga de funções é um polimorfismo estático que permite que um programa possa declarar várias funções com o mesmo nome, diferenciando entre si pela quantidade de parâmetros apresentados e por seus respectivos tipos de dado. A sobrecarga de operadores também é um polimorfismo estático que permite que a definição de certos operadores resultem em uma chamada de função que depende dos tipos de dado dos operadores sendo utilizados.

O polimorfismo por herança é um exemplo de polimorfismo dinâmico no qual ponteiros de uma classe base podem referenciar objetos de classes derivadas, o que permite que uma chamada de função virtual seja resolvida em tempo de execução de código. Ponteiros e referências de uma classe base podem referenciar objetos de qualquer classe derivada de si, o que permite que arranjos e outros containers de um dado tipo possam armazenar ponteiros de diversos tipos de dados, o que não poderia ser feito de outra maneira em C++. Como não é possível descobrir se a conversão do tipo base para o tipo derivado é segura em tempo de compilação, a verificação deve ser feita durante a execução do código. Para isso é fornecido o operador dynamic_cast, que permite tentar a conversão segura de uma classe mais abstrata (classe base) para outra mais específica (classe derivada). Para sua utilização a linguagem dispõe do RTTI, uma técnica para manter em memória informações sobre o tipo de dado de objetos. Caso a conversão não seja possível uma exceção específica é lançada.

[editar] Regra dos três

Uma regra informal no desenvolvimento orientado a objeto em C++ clama que se uma classe ou estrutura possui um dos seguintes itens, ela provavelmente deveria ter todos os três[21]: destrutor, construtor de cópia e operador de atribuição (=).

Esse três métodos são funções membros especiais criadas pelo compilador automaticamente se não são definidas pelo desenvolvedor[22]. Se um desses métodos é definido explicitamente pelo desenvolvedor, isso significa que a versão gerada pelo compilador não serve para um dos casos, e portanto muito provavelmente também não serve para os outros casos.

Um adendo à essa regra diz respeito à técnica RAII[23]: se ela for usada então o destrutor pode ser deixado sem definição (também conhecida como "regra dos dois"[24]).

[editar] Tratamento de exceções

Ver artigo principal: Tratamento de exceções

O tratamento de exceção é um mecanismo desenvolvido para lidar com a ocorrência de algumas condições (chamadas exceções) que alteram o funcionamento normal do fluxo de um programa de computador. O C++ suporta tal tratamento, de forma que o estado atual de um programa após uma exceção é alterado automaticamente para outro estado pré-definido para a recuperação do sistema.

Para isso foram adicionadas à linguagem as palavras reservadas try e catch. A primeira especifica um bloco de código que será vigiado em relação à exceções, de forma que se uma for identificada, o fluxo de programa será desviado para um bloco especificado pela segunda palavra reservada. Para um dado bloco try podem existir diversos blocos catch, capturando exceções de diferentes tipos de dado. Alternativamente, a sintaxe catch(...) foi introduzida para especificar um bloco de tratamento de exceção independente do tipo da exceção, genérico.

O conceito puro da Ciência da Computação para tratamento de exceções ainda inclui o bloco de instruções finally, que indica um bloco de código executado após um bloco try caso nenhuma exceção tenha sido lançada, indicando sucesso na operação. Tal abordagem não foi adicionada ao C++, sendo substituível por outras técnicas como RAII[23][25]. De qualquer forma, é possível que essa funcionalidade seja adicionada na próxima especificação da linguagem.

[editar] Espaço de nomes

Ver artigo principal: Espaço de nomes

O C++ introduziu os espaços de nomes para a organização das bibliotecas, e sua função é agrupar um contexto para identificadores (variáveis, funções, classes, estruturas, entre outros). No contexto de sistemas operativos, o espaço de nomes poderia ser representado por diretórios. Toda a biblioteca padrão está contida no espaço de nomes std (abreviação de standard, que em inglês significa padrão). Para utilizar um espaço de nomes pode ser feita tanto uma declaração global dos espaços quanto local. Uma declaração global é normalmente inserida no início dos módulos, após a importação dos módulos externos, utilizando a palavra reservada using (como em using namespace std;, ver exemplo contextualizado em anexo). Ela também pode ser usada em um escopo pré-determinado por um bloco de código. Uma declaração local é inserida antes de invocar o identificador envolvido, utilizando o operador de resolução de escopo :: (como em std::cout, ver exemplo contextualizado em anexo). A declaração global é útil para reduzir a quantidade de código produzido, sub entendendo a origem dos identificadores utilizados em todo um escopo. Apesar disso, ela deixa margem à ambiguidades, pois é possível que um mesmo identificador esteja presente em mais de um espaço de nome importado no módulo. Para eliminar esse problema deve-se, além de utilizar a declaração global, declarar o identificador ambíguo localmente cada vez que ele for utilizado.

Em determinadas ocasiões, espaços de nome não considerados durante a primeira verificação do espaço de nomes de uma função podem também ser utilizados na busca, dependendo dos tipos de dados utilizados nos argumentos. A técnica, chamada busca de nomes dependente de argumento ou Koening lookup, ocorre quando a busca explícita pela função não encontra correspondente, começando então a procurar por espaços de nomes associados. Um padrão muito utilizado pela Standard Template Library é declarar sobrecarga de operadores que somente são encontrados pelo compilador através dessa técnica.

[editar] Ponteiros e referências

Ver artigo principal: Ponteiro (programação)

O C++ herdou a funcionalidade de ponteiros do C e toda a aritmética de ponteiros disponível para aquela linguagem: tratando um ponteiro como um tipo inteiro é possível mover-se facilmente por regiões de memória. A instância de um ponteiro em C++ é uma variável que armazena um endereço de memória, e que pode ser nula. A biblioteca padrão ainda fornece auto_ptr, uma espécie de ponteiro inteligente para contagem de referências que pode ser utilizado em algumas situações como uma alternativa segura aos ponteiros primitivos do C, automatizando o processo de desalocação de memória do objeto apontado pelo ponteiro.

Por questões de segurança, o C++ introduziu também o tipo de dado referência, um tipo mais restrito de ponteiro. Uma referência definida para outro objeto não pode ser mais referenciada, qualquer ocorrência do nome no código diz respeito ao objeto referenciado. Como consequência, não é possível realizar "aritmética de referências". Outra consequência é que não é possível alterar uma referência para que ela defina outro objeto; após definida, essa relação vale para todo o tempo de vida. Em contrapartida, um mesmo ponteiro frequentemente aponta para diferentes áreas de memória.

Apesar de teoricamente possível[26], a existência de referências nulas não é considerada, podendo-se assumir que uma referência sempre indica um objeto válido em memória.

[editar] Incompatibilidade com C

É incorreto considerar o C++ como um super conjunto de C, isto é, uma linguagem que implementa o C completamente e que adiciona novas funcionalidades[27]. Grande parte de código C pode ser perfeitamente compilado em C++, mas existem algumas pequenas diferenças sintáticas e semânticas entre as linguagens que tornam alguns trechos de código C válidos em código C++ inválido, ou códigos que exibem comportamentos diferentes em cada linguagem[28].

Talvez a diferença mais comum é que C permite a conversão implícita entre o tipo de dado void* para ponteiros para outros tipos, algo que o C++ não permite. Logo, o seguinte código em C é válido:

int *i = malloc(sizeof(int) * 5);         /* conversão implícita de void* para int* */

Para assegurar-se que o código funcione tanto em C quanto C++ é necessário explicitar a conversão:

int *i = (int *) malloc(sizeof(int) * 5); /* conversão explícita de void* para int* */

Outra questão de portabilidade entre as linguagens é o fato do C++ adicionar várias novas palavras reservadas, como new e class, que podem ser utilizadas como identificadores (por exemplo nomes de variáveis) em C, gerando incompatibilidade.

Algumas outras incompatibilidades foram removidas no padrão C99, que agora suporta facilidades como comentários por //[28]. Tanto C99 quanto C++ definem o tipo de dado bool e suas respectivas constantes true e false. Apesar disso, enquanto a definição no C++ é embarcada na própria linguagem, tornando tais elementos palavras reservadas, em C tais identificadores são declarados através da biblioteca padrão stdbool.h.

Algumas construções sintáticas são válidas tanto em C quanto C++, mas produzem resultado diferente. Por exemplo, o valor literal 'a' possui tipo de dado int em C e char em C++, o que significa que uma chamada sizeof('a'), que retorna a quantidade de bytes ocupada pelo identificador, pode resultar em resultados diferentes entre as duas linguagens. Na prática, esse exemplo específico não é realmente um problema já que caracteres literais são convertidos para o tipo int implicitamente pelo compilador tanto em C quanto em C++.

[editar] Análise sintática do código fonte

Como a gramática C++ é bastante complexa, é difícil construir um bom analisador sintático para código fonte C++ utilizando algoritmos clássicos como o LALR(1)[29]. Por exemplo, com o LALR é possível analisar código Java[30]. A flexibilidade da linguagem também é fruto de ambiguidades que um analisador simples não consegue distinguir. Por esse motivo, existem poucas ferramentas para análise e transformação não trivial de código, como refatoração. Em suas primeiras especificações o C++ era uma gramática LALR, entretanto, com a adição de funcionalidades como espaço de nomes, exceções, templates e o tipo bool, essa característica logo se tornou inválida.[29]

A análise sintática não é a tarefa mais difícil na construção de uma ferramenta C++. Outras tarefas incluem entender o significado dos identificadores do programa que um compilador deve possuir. Sistemas práticos de processamento não devem somente analisar o código fonte, mas também compreender exatamente cada identificador em diferentes usos, lidando com as regras de escopo de identificadores (ver um código contextualizado em anexo).

O grupo Boost possui um projeto para a construção de um analisador sintático C++ com base na biblioteca Spirit[31], de forma que se torna um método padrão e livre de análise sintática para a linguagem.

[editar] Críticas

Wikiquote
O Wikiquote tem uma coleção de citações de ou sobre: Bjarne Stroustrup.
C faz com que dar um tiro no pé seja fácil; C++ torna isso mais difícil, mas quando nós o fazemos arrebentamos com a perna toda.
Bjarne Stroustrup

A citação de Stroutrup trata com humor o fato de o C++, ao possibilitar a programação de alto nível, ter facilitado a codificação de algoritmos e organização de projetos em relação ao C, uma linguagem que requer constante atenção contra erros lógicos de programação devido à sua alta flexibidade. Por outro lado, o C++ possui nuances da sintaxe e semântica da linguagem muito sutis, difíceis de serem identificados, e que quando não percebidos podem levar a comportamentos indesejados no código.

[editar] Vantagens

  • Produção de código o quanto mais eficiente possível.
  • Possibilidade em programação de alto e baixo nível.
  • Alta flexibilidade, portabilidade e consistência.
  • Adequado para grandes projetos.
  • Ampla disponibilidade e suporte, devido principalmente à grande base de desenvolvedores.
  • Não está sob o domínio de uma empresa (em contraste do JavaSun ou Visual BasicMicrosoft). Padronização pela ISO.
  • Grandes possibilidades para a metaprogramação e programação genérica.
  • Compatilidade com C, resultando em vasta base de códigos.

[editar] Desvantagens

  • Compatilidade com o C herdou os problemas de entendimento de sintaxe do mesmo.
  • Os compiladores atuais nem sempre produzem o código mais otimizado, tanto em velocidade quando tamanho do código.
  • Grande período para o aprendizado.
  • A biblioteca padrão não cobre áreas importantes da programação, como threads, conexões TCP/IP, interface gráfica e manipulação de sistemas de arquivos, o que implica na necessidade de criação de bibliotecas próprias para tal, que pecam em portabilidade.
  • Devido à grande flexibilidade no desenvolvimento, é recomendado o uso de padrões de programação mais amplamente que em outras linguagens.

[editar] Pessoas notáveis

O desenvolvimento da linguagem C++ é fruto do trabalho de milhares de pessoas associadas à academia e à indústria de software, e pode consistir na utilização da linguagem, em seu ensino, na construção de bibliotecas de rotinas ou na participação no comitê de padronização, entre outras atividades. Algumas pessoas tiveram participação fundamental durante a história para o desenvolvimento[32]. Primeiramente, o próprio Bjarne Stroustrup, criador da linguagem e de seu primeiro compilador. O cientista ainda participa na padronização e divulga o C++ no meio acadêmico. Andrew Koenig é outro pesquisador notável, bastante atuante na padronização e creditado pela técnica Koenig lookup (demonstrada em anexo). Já Scott Meyers é um doutor em ciência da computação, e escritor de diversos livros sobre o desenvolvimento de software utilizando a linguagem. Assim como Meyers, Herb Sutter é escritor de diversos livros sobre C++ e centenas de colunas e artigos, e um notável pesquisador sobre programação concorrente e multitarefa. Andrei Alexandrescu é considerado um dos maiores especialistas em programação C++ avançada. Na área de programação genérica destaca-se o programador russo Alexander Stepanov, a figura chave na criação da Standard Template Library.

[editar] Ferramentas

[editar] Ambientes de desenvolvimento

Abaixo é mostrada uma lista dos principais ambientes de desenvolvimento C++, sejam eles compiladores ou ambientes de desenvolvimento integrado (IDE).

Nome Comentário É software livre? É compilador? É IDE? Plataforma
G++ Um componente do GCC, compilador padrão do Projecto GNU Sim Sim Não Unix, Linux, Mac OS X, Windows e AmigaOS
Dev-C++ IDE livre famosa entre iniciantes. Seu compilador é o MinGW, uma versão do G++ para Windows. Sim Não Sim Windows
Intel C++ Produz código otimizado para processadores Intel Não Sim Não Windows e Linux
Microsoft Visual C++ É o mais conhecido para a plataforma Windows, com ferramentas e tecnologias auxiliares para desenvolvimento nessa plataforma (como MFC, ATL, COM, entre outras). Oferece ainda uma versão gratuita com restrições de uso[33] Não Sim Sim Windows
C++ Builder Ferramenta da Borland que oferece versões antigas gratuitas sem presença de IDE. Possui integração com Delphi Não Sim Sim Windows e Linux
Open Watcom Suporta plataformas antigas, até então sem suporte completo à biblioteca padrão Sim Sim Sim DOS, Windows, OS/2 e Netware
Comeau C++ Pode ser experimentado pela Internet[34] Não Sim Não Windows, Linux e Solaris
Turbo C++ Possui versão gratuita[35] no sítio oficial e também uma versão paga[36]. É similar ao C++ Builder. Não Sim Sim Windows
Eclipse Disponível para C++ através da extensão CDT[37]. Sim Não Sim Windows, Linux
Anjuta Suporta muitas capacidades avançadas como gerenciamento de projetos e um poderoso editor de código fonte. Uma nova versão do Anjuta (Anjuta 2.*) que integra o Glade está em desenvolvimento ativo. Sim Não Sim Linux
Code::Blocks Ambiente aberto e multi-plataforma, em sua versão para Windows utiliza o compilador MinGW, apesar de também suportar outros compiladores como o Visual C++, Digital Mars, Borland C++ 5.5 e Open Watcom[38]. Sim Não Sim Windows, Linux
Digital Mars Não Sim Sim Windows, DOS

[editar] Aplicativos desenvolvidos em C++

Abaixo segue uma lista de exemplos de aplicativos parcial ou totalmente escritos em C++[39].

Notas e referências

  1. Bjarne Stroustrup (maio de 2005). The Design of C++0x (PDF) (inglês). C/C++ Users Journal.
  2. Danny Kalev (17 de novembro de 2006). C++09: A Glimpse into the Future (inglês). DevSource (Microsoft). Página visitada em 16 de outubro de 2007.
  3. Bjarne Stroustrup. Quando o C++ foi inventado? (inglês). FAQ de Bjarne Stroustrup.
  4. 4,0 4,1 Alexander Stepanov e Meng Lee (7 de março de 1994). The Standard Template Library (inglês). Hewlett-Packard, Technical Report X3J16/94-0095, WG21/N0482.
  5. (en) Descrição da norma
  6. Bjarne Stroustrup. Where did the name "C++" come from?. FAQ de Bjarne Stroustrup. Página visitada em 8 de março de 2007.
  7. (en) Mais informações sobre o C++ ABI podem ser obtidas no sumário sobre a extensão
  8. Um exemplo é o livro de Ivor Horton:
    Ivor Horton. Beginning ANSI C++. 3.ed. APRESS, 2004. 827 p. ISBN 1-59059-227-1
  9. Herb Sutter, Tom Plum (3 de março de 2003). Why We Can’t Afford Export (inglês). Sítio oficial do comitê de padronização do C++. Página visitada em 10 de setembro de 2007.
  10. (en) J16 Reunião 36/WG21, realizada entre 7 e 11 de abril de 2003]
  11. Herb Sutter (7 de fevereiro de 2006). ISO C++0x: Complete Public Review Draft In October 2007? (inglês). Página visitada em 21 de abril de 2007.
  12. John Maddock (3 de março de 2003). A Proposal to add Regular Expressions to the Standard Library (inglês). Comitê de padronização do C++. Página visitada em 9 de janeiro de 2008.
  13. Jaakko Järvi (10 de setembro de 2002). Proposal for adding tuple types into the standard library (PDF) (inglês). Comitê de padronização do C++. Página visitada em 9 de janeiro de 2008.
  14. Jaakko Järvi et al (28 de abril de 2003). Decltype and auto (PDF) (inglês). Comitê de padronização do C++. Página visitada em 9 de janeiro de 2008.
  15. Jeremiah Willcock et al (26 de fevereiro de 2006). Lambda expressions and closures for C++ (PDF) (inglês). Comitê de padronização do C++. Página visitada em 8 de março de 2007.
  16. Valentin Samko (23 de fevereiro de 2006). A proposal to add lambda functions to the C++ standard (PDF) (inglês). Comitê de padronização do C++. Página visitada em 9 de janeiro de 2008.
  17. Herb Sutter e Francis Glassborow (13 de fevereiro de 2004). Delegating Constructors (PDF) (inglês). Comitê de padronização do C++. Página visitada em 9 de janeiro de 2008.
  18. Stanley B. Lippman. Inside the C++ Object Model. Addison-Wesley Professional, 1996. 304 p. ISBN 978-0201834543
  19. (en) Processo de compilação explicado pela IBM
  20. (en) Processo de compilação explicado pela HP
  21. Marshall P. Cline; Greg Lomow; Mike Girou. C++ FAQs. 2.ed. Addison-Wesley Professional, 1998. 624 p. ISBN 978-0201309836
  22. O construtor padrão também é criado automaticamente pelo compilador caso o desenvolvedor não tenha definido nenhum outro construtor para a classe.
  23. 23,0 23,1 Bjarne Stroustrup. resource acquisition is initialization (inglês). Glossário de Bjarne Stroustrup.
  24. Bjorn Karlsson e Matthew Wilson (1 de outubro de 2004). The Law of The Big Two (inglês). C++ Source. Página visitada em 21 de abril de 2007.
  25. Herb Sutter realiza uma comparação entre as técnicas RAII e Dispose (que depende do conceito de finally) em seu blog pessoal:
    Herb Sutter (31 de agosto de 2004). C++ RAII compared with Java Dispose pattern (inglês). Página pessoal do autor. Página visitada em 29 de setembro.
  26. Dado um tipo de dado T, uma referência pode ser definida para nulo através de T& var = *(T*)0;. Notar entretanto que obter o conteúdo de nulo resulta em comportamento indefinido, o que indica má prática de programação.
  27. Bjarne Stroustrup. Is C a subset of C++? (inglês). FAQ no sítio pessoal do autor. Página visitada em 7 de fevereiro de 2008.
  28. 28,0 28,1 David R. Tribble (5 de agosto de 2001). Incompatibilities Between ISO C and ISO C++ (inglês). Sítio pessoal do autor. Página visitada em 28 de setembro de 2007.
  29. 29,0 29,1 Andy (Março de 2001). Parsing C++ (inglês). Página visitada em 7 de fevereiro de 2008.
  30. The Java Language Specification LALR(1) Grammar (inglês). The Java Language Specification. Sun Microsystems (3 de abril de 1998). Página visitada em 7 de fevereiro de 2008.
  31. Boost.Spirit based C++ parser (library) (inglês). Grupo Boost. Página visitada em 29 de abril de 2007.
  32. Scott Meyers (30 de agosto de 2006). The Most Important C++ People...Ever (inglês). Artima Developer. Página visitada em 30 de setembro de 2007.
  33. Visual Studio Express (inglês). MSDN, sítio da Microsoft Corporation. Página visitada em 25 de outubro de 2007.
  34. Test Drive Comeau C++ Online (inglês). Comeau Computing (31 de março de 2007). Página visitada em 7 de fevereiro de 2008.
  35. David Intersimone. Antique Software: Turbo C++ version 1.01 (inglês). Página visitada em 24 de outubro de 2007.
  36. Turbo C++ (inglês). Borland. Página visitada em 24 de outubro de 2007.
  37. Eclipse C/C++ Development Tooling - CDT (inglês). Eclipse Foundation. Página visitada em 24 de outubro de 2007.
  38. Code::Blocks Features (inglês). Sítio oficial do Code::Blocks. Página visitada em 24 de outubro de 2007.
  39. Bjarne Stroustrup. C++ Applications (inglês). Sítio pessoal de Stroustrup.
  40. (en) Descrição do Googlebot, desenvolvido em C++
  • Bjarne Stroustrup. The Design and Evolution of C++. Addison-Wesley, 1994. ISBN 0-201-54330-3
  • Andrei Alexandrescu e Herb Sutter. C++ Design and Coding Standards: Rules and Guidelines for Writing Programs. Addison-Wesley, 2004. ISBN 0-321-11358-6

[editar] Ver também

Wikibooks
O Wikilivros possui livros e publicações sobre: Programar em C++
Wikibooks
O Wikilivros possui livros e publicações sobre: Referência rápida de C++
Wikcionário
O Wikcionário possui o verbete: C++

[editar] Ligações externas

[editar] Grupos de discussão e de suporte

[editar] Material de estudo