C ++ - C++

Da Wikipédia, a enciclopédia livre

C ++
ISO ++ Logo.svg C
Paradigma Multi-paradigma : processual , funcional , orientada a objeto , genérico
Projetado por Bjarne Stroustrup
Apareceu pela primeira vez 1985 ; Há 33 anos ( 1985 )
Versão estável
ISO / IEC 14882: 2017/01 de dezembro de 2017 ; 11 meses atrás ( 2017/12/01 )
disciplina Typing Estática , nominative , parcialmente inferida
linguagem de implementação C ++ ou C
extensões de arquivo .C, .cc, .cpp, .cxx, .c ++ , .h, .hh, .hpp, .hxx, .h ++
Local na rede Internet isocpp .org
grandes implementações
LLVM Clang , GCC , Microsoft Visual C ++ , Embarcadero C ++ Builder , Intel C ++ Compiler , IBM XL C ++ , EDG
Influenciado por
Ada , ALGOL 68 , C , CLU , ML , Simula
Influenciado
Ada 95 , C # , C99 , Chapel , Clojure , D , Java , Lua , Nim , Perl , PHP , Python , Ferrugem

C ++ ( / ˌ s i ˌ p l ʌ s p l ʌ s / "ver plus plus") é uma linguagem de programação de propósito geral . Tem imperativas , orientadas a objetos e genérico recursos de programação, além de fornecer instalações de baixo nível de memória manipulação.

Ele foi projetado com um viés em direção a programação do sistema e embutido , sistemas de recursos limitados e grandes, com desempenho , eficiência e flexibilidade de uso de seus destaques de design. C ++ também foi encontrado útil em muitos outros contextos, com pontos fortes sendo infra-estrutura de software e aplicações de recursos limitados, incluindo aplicações desktop , servidores (por exemplo, e-commerce , busca na Web ou SQL servidores), e aplicações de desempenho crítico (por exemplo, centrais telefônicas ou sondas espaciais ). C ++ é uma linguagem compilada , com implementações de TI disponíveis em várias plataformas. Muitos fornecedores oferecem compiladores C ++ , incluindo a Free Software Foundation , Microsoft , Intel e IBM .

C ++ é padronizado pela Organização Internacional de Normalização (ISO), com a última versão padrão ratificado e publicado pela ISO em dezembro de 2017 como ISO / IEC 14882 : 2017 (informalmente conhecido como C ++ 17 ). A linguagem C ++ foi inicialmente padronizado em 1998 como ISO / IEC 14882: 1998 , que foi então alterado pelo 03 C ++ , C ++ 11 e C ++ 14 padrões. A corrente C ++ 17 Norma substitui-los com novos recursos e uma alargada biblioteca padrão . Antes da padronização inicial em 1998, C ++ foi desenvolvido por Bjarne Stroustrup no Bell Labs desde 1979, como uma extensão da linguagem C como ele queria uma linguagem eficiente e flexível semelhante a C, que também forneceu recursos de alto nível para a organização do programa. C ++ 20 é o próximo padrão planejado depois, mantendo com a raia atual de uma nova versão a cada três anos.

Muitas outras linguagens de programação ter sido influenciado por C ++, incluindo C # , D , Java , e as versões mais recentes de C.

História

Bjarne Stroustrup , o criador de C ++

Em 1979, Bjarne Stroustrup , um dinamarquês cientista da computação , começou a trabalhar em " C com Classes ", o antecessor para C ++. A motivação para a criação de uma nova linguagem se originou da experiência de Stroustrup na programação para o doutorado tese. Stroustrup descobriu que Simula tinha recursos que estavam muito útil para o desenvolvimento de software de grande porte, mas a linguagem era muito lenta para uso prático, enquanto BCPL foi rápido, mas demasiado baixo nível para ser adequado para o desenvolvimento de software de grande porte. Quando Stroustrup começou a trabalhar na AT & T Bell Labs , ele teve o problema de analisar o UNIX kernel do que diz respeito à computação distribuída . Lembrando seu Ph.D. experiência, Stroustrup estabelecidos para melhorar a C linguagem com Simula características -como. C foi escolhido porque era de uso geral, rápido, portátil e amplamente utilizado. Bem como C e influências de Simula, outros idiomas também influenciada C ++, incluindo ALGOL 68 , Ada , CLU e ML .

Inicialmente, "C com Classes" do Stroustrup adicionou recursos para o compilador C, CPRE, incluindo aulas , classes derivadas , tipagem forte , inlining e argumentos padrão .

Em 1983, "C com Classes" foi renomeado para "C ++" ( ++sendo o operador de incremento em C), adicionando novas funcionalidades que incluem funções virtuais , nome da função e operador de sobrecarga , referências, constantes, alocação de memória livre-store tipo seguro ( nova / delete), melhorou a verificação de tipo e estilo BCPL única linha comenta com duas barras ( //). Além disso, incluiu o desenvolvimento de um compilador independente para C ++, Cfront .

Em 1985, a primeira edição do The C ++ Programming Language foi lançado, que se tornou a referência definitiva para a linguagem, como ainda não havia um padrão oficial. A primeira implementação comercial do C ++ foi lançado em outubro do mesmo ano.

Em 1989, C ++ 2.0 foi lançado, seguido pela segunda edição atualizada da linguagem de programação C ++ em 1991. Os novos recursos na versão 2.0 incluída herança múltipla, classes abstratas, funções de membro estático, as funções de membro const , e membros protegidos. Em 1990, O anotada C ++ Manual de Referência foi publicado. Este trabalho tornou-se a base para a futura norma. Adições de recursos posteriores incluíram templates , exceções , namespaces , novos moldes , e um tipo booleano .

Após a atualização 2.0, C ++ evoluiu de forma relativamente lenta, até que, em 2011, o C ++ 11 padrão foi lançado, adicionando vários novos recursos, ampliando a biblioteca padrão ainda mais, e proporcionando mais facilidades para os programadores C ++. Após um menor C ++ 14 actualização lançada em Dezembro de 2014, várias novas adições foram introduzidos em C ++ 17 , e mais alterações previsto para 2020.

A partir de 2017, C ++ continua a ser a terceira linguagem de programação mais popular, atrás de Java e C.

Em 3 de janeiro de 2018, Stroustrup foi anunciado como o vencedor de 2018 do Prêmio Draper Stark Charles de Engenharia "para conceituar e desenvolver a linguagem C ++".

Etimologia

De acordo com Stroustrup: "o nome significa a natureza evolutiva das mudanças de C". Este nome é creditada a Rick Mascitti (meados de 1983) e foi usado pela primeira vez em dezembro de 1983. Quando Mascitti foi interrogado informalmente em 1992 sobre a nomeação, ele indicou que foi dada em uma língua-de-bochecha espírito. O nome vem do C ++ operador (o que incrementa o valor de uma variável ) e um comum convenção de nomenclatura de usar "+" para indicar um programa de computador avançado.

Durante o período de desenvolvimento do C ++, a linguagem tinha sido referido como 'novo C' e 'C com Classes' antes de adquirir o seu nome final.

Filosofia

Ao longo da vida do C ++, seu desenvolvimento e evolução tem sido guiado por um conjunto de princípios:

  • Deve ser conduzido por problemas reais e suas características devem ser úteis imediatamente em programas do mundo real.
  • Cada recurso deve ser implementável (com uma maneira razoavelmente óbvio para fazê-lo).
  • Os programadores devem ser livres para escolher o seu próprio estilo de programação, e que estilo deve ser totalmente suportado pelo C ++.
  • Permitindo uma característica útil é mais importante do que a prevenção cada possível desvio de C ++.
  • Ele deve fornecer instalações para a organização de programas em partes separadas bem definidas, e fornecer instalações para combinar peças desenvolvidas separadamente.
  • Nenhuma violação implícitas do sistema de tipo (mas permitir que violações explícitas, ou seja, aqueles explicitamente solicitado pelo programador).
  • tipos criados pelo usuário precisa ter o mesmo suporte e desempenho como tipos de embutidos.
  • recursos não utilizados não devem impactar negativamente executáveis ​​criado (por exemplo, em desempenho inferior).
  • Não deve haver nenhuma linguagem sob C ++ (exceto linguagem assembly ).
  • C ++ deve trabalhar ao lado de outros existentes linguagens de programação , ao invés de promover o seu próprio separado e incompatível ambiente de programação .
  • Se a intenção do programador é desconhecida, permitir que o programador especifique-fornecendo um controle manual.

estandardização

Ano C ++ Padrão Nome informal
1998 ISO / IEC 14882: 1998 C ++ 98
2003 ISO / IEC 14882: 2003 C ++ 03
2011 ISO / IEC 14882: 2011 C ++ 11 , ++ 0x C
2014 ISO / IEC 14882: 2014 14 C ++ , C ++ 1a
2017 ISO / IEC 14882: 2017 C ++ 17 1z, C ++
2020 estar determinado C ++ 20

C ++ é padronizado por uma norma ISO grupo de trabalho conhecida como JTC1 / SC22 / WG21 . Até agora, ele publicou cinco revisões do C ++ padrão e está actualmente a trabalhar na próxima revisão, C ++ 20 .

Em 1998, o grupo de trabalho normalizado ISO C ++ para a primeira vez como a norma ISO / IEC 14882: 1998 , que é informalmente conhecidos como C ++ 98 . Em 2003, publicou uma nova versão do padrão C ++ chamada ISO / IEC 14882: 2003 , que fixa os problemas identificados em C ++ 98 .

A próxima grande revisão da norma foi informalmente conhecido como "C ++ 0x", mas não foi liberado até 2011. C ++ 11 (14882: 2011) incluiu muitas adições tanto para o núcleo da linguagem e da biblioteca padrão.

Em 2014, C ++ 14 (também conhecido como 1a C ++) foi lançado como uma pequena extensão para C ++ 11 , apresentando principalmente correções de bugs e pequenas melhorias. O projecto de procedimentos de voto Norma Internacional concluída em meados de agosto de 2014.

Depois de C ++ 14, uma grande revisão C ++ 17 , informalmente conhecido como C ++ 1z, foi concluído pela Comissão ++ C a ISO em meados de Julho 2017 e foi aprovado e publicado em Dezembro de 2017.

Como parte do processo de normalização, ISO também publica relatórios técnicos e especificações :

  • ISO / IEC TR 18015: 2006 sobre o uso de C ++ em sistemas embarcados e sobre as implicações de recursos da linguagem e da biblioteca C ++ desempenho,
  • ISO / IEC TR 19768: 2007 (também conhecido como o Relatório C ++ técnica 1 ) em extensões da biblioteca na sua maioria integrados em C ++ 11 ,
  • ISO / IEC TR 29124: 2010 em funções matemáticas especiais,
  • ISO / IEC TR 24733: 2011 em decimal ponto flutuante aritmética,
  • ISO / IEC TS 18822: 2015, a biblioteca de sistema de arquivos padrão,
  • ISO / IEC TS 19570: 2015 em paralelas versões dos algoritmos biblioteca padrão,
  • ISO / IEC TS 19841: 2015, software de memória transacional ,
  • ISO / IEC TS 19568: 2015 com uma nova série de extensões de biblioteca, alguns dos quais já estão integrados em C ++ 17 ,
  • ISO / IEC TS 19217: 2015 no C ++ conceitos

Mais especificações técnicas estão em desenvolvimento e aprovação pendente, incluindo as extensões da biblioteca de simultaneidade, uma biblioteca padrão de rede, varia, e módulos.

Língua

A linguagem C ++ tem dois componentes principais: um mapeamento directo de recursos de hardware fornecida principalmente pelo subconjunto C, e captações de zero-gerais com base nesses mapeamentos. Stroustrup descreve C ++ como "uma linguagem de programação abstração leve [projetados] para a construção e usando abstrações eficientes e elegantes"; e "oferecendo acesso ao hardware e abstração é a base de C ++. Fazê-lo de forma eficiente é o que o distingue de outras línguas".

C ++ herda a maioria de sintaxe do C . O seguinte é a versão de Bjarne Stroustrup do programa mundial Olá que utiliza a biblioteca padrão C ++ instalação fluxo para escrever uma mensagem para a saída padrão :

1 #include <iostream>
2 
3 int main()
4 {
5     std::cout << "Hello, world!\n";
6 }

armazenamento de objetos

Como em C, C ++ suporta quatro tipos de gerenciamento de memória : objetos duração de armazenamento estático, objetos de armazenamento de fio de duração, objetos automáticos duração de armazenamento e objetos duração de armazenamento dinâmico.

objectos de duração de armazenamento estático

Objetos de duração de armazenagem estática são criadas antes main()é introduzido (veja exceções abaixo) e destruiu na ordem inversa da criação após main()saídas. A ordem exata da criação não é especificado pelo padrão (embora existam algumas regras definidas abaixo) para permitir implementações alguma liberdade em como organizar a sua implementação. Mais formalmente, objetos deste tipo têm um tempo de vida que "deve durar para a duração do programa".

Objectos de duração de armazenamento estático são inicializados em duas fases. Primeiro, "inicialização estática" é realizada, e só depois de tudo inicialização estática é realizada "inicialização dinâmica" é executada. Na inicialização estática, todos os objetos são primeiramente inicializados com zeros; Depois disso, todos os objectos que têm uma fase de inicialização constante são inicializados com a expressão constante (isto é, variáveis inicializado com um ou literal constexpr). Embora não seja especificado no padrão, a fase de inicialização estática pode ser concluída em tempo de compilação e salvos na partição de dados do executável. Inicialização dinâmico envolve toda a inicialização objecto feito através de uma chamada construtor ou função (a não ser que a função é marcado com constexpr, em C ++ 11). A ordem de inicialização dinâmico é definido como o fim da declaração na unidade de compilação (ou seja, o mesmo ficheiro). Não há garantias são fornecidas sobre a ordem de inicialização entre unidades de compilação.

objetos duração de armazenamento Tópico

Variáveis ​​deste tipo são muito semelhantes aos objetos duração de armazenamento estático. A principal diferença é o tempo de criação é apenas antes para thread criação e destruição é feito depois que o segmento foi unido.

objetos duração de armazenamento automático

Os tipos mais comuns de variáveis em C ++ são variáveis locais dentro de uma função ou bloco, e variáveis temporárias. A característica comum sobre variáveis automáticas é que eles têm uma vida que está limitada ao âmbito da variável. Eles são criados e potencialmente inicializado no ponto de declaração (ver detalhes abaixo) e destruído no reverso ordem da criação quando o escopo é deixado. Isso é implementado pela alocação na pilha .

As variáveis locais são criados como o ponto de execução passa o ponto de declaração. Se a variável tem um construtor ou inicializador este é usado para definir o estado inicial do objecto. As variáveis locais são destruídos quando o bloco local ou função que eles são declarados no está fechado. Destruidores C ++ para as variáveis locais são chamados no final da vida útil do objeto, permitindo uma disciplina de gestão de recursos automática denominado RAII , que é amplamente utilizado em C ++.

membro variáveis ​​são criados quando o objeto pai é criado. membros da matriz são inicializados de 0 até o último membro da matriz em ordem. variáveis ​​de membro são destruídos quando o objeto pai é destruído na ordem inversa de criação. ou seja, se o pai é um "objeto automático", em seguida, ele será destruído quando ele sai do escopo que desencadeia a destruição de todos os seus membros.

As variáveis temporárias são criados como resultado da avaliação da expressão e são destruídos quando a instrução contendo a expressão tenha sido completamente avaliado (geralmente no ;no final de uma instrução).

objetos duração de armazenamento dinâmico

Esses objetos têm uma vida útil dinâmica e são criados com uma chamada para newe destruídos explicitamente com uma chamada para delete.

Modelos

Modelos C ++ permitem programação genérica . C ++ suporta a função, classe, alias e modelos de variáveis. Modelos podem ser parametrizados por tipos, constantes de tempo de compilação e outros modelos. Os modelos são implementados por instanciação em tempo de compilação. Para instanciar um modelo, compiladores substituir argumentos específicos para os parâmetros de um modelo para gerar uma função concreta ou instância de classe. Algumas substituições não são possíveis; estes são eliminados por uma política de resolução de sobrecarga descrito pela frase " falha de Substituição não é um erro " (SFINAE). Os modelos são uma ferramenta poderosa que pode ser usado para programação genérica , modelo metaprogramming , e otimização de código, mas este poder implica um custo. Use os modelos podem aumentar o tamanho do código, porque cada instanciação de modelo produz uma cópia do código do modelo: um para cada conjunto de argumentos de modelo, no entanto, esta é a mesma ou menor quantidade de código que seria gerado se o código foi escrito à mão. Isto está em contraste com os genéricos observados em outras línguas (por exemplo, tempo de execução- Java ) onde em tempo de compilação do tipo é apagada e um corpo único modelo é preservada.

Os modelos são diferentes das macros : enquanto ambos os recursos de linguagem de tempo de compilação permitir a compilação condicional, modelos não estão restritos a substituição lexical. Os modelos são conscientes da semântica e sistema de tipos de sua língua companheiro, bem como todas as definições de tipo de tempo de compilação, e pode executar operações de alto nível, incluindo o controle de fluxo programático com base na avaliação de parâmetros estritamente verificados digita. As macros são capazes de controlo condicional sobre compilação com base em critérios pré-determinados, mas não pode instanciar novos tipos, recursivo, ou realizar a avaliação tipo e no efeito estão limitados a pré-compilação texto de substituição de texto e inclusão / exclusão. Em outras palavras, as macros podem controlar o fluxo de compilação com base em símbolos pré-definidos, mas não pode, ao contrário de modelos, instanciar independentemente novos símbolos. Os modelos são uma ferramenta para estática polimorfismo (veja abaixo) e programação genérica .

Além disso, os modelos são um mecanismo de tempo de compilação em C ++ que é Turing completo , o que significa que qualquer expressible computação por um programa de computador pode ser calculado, de alguma forma, por um metaprograma modelo antes de tempo de execução.

Em resumo, um modelo é uma função parametrizada em tempo de compilação ou classe escrita sem o conhecimento dos argumentos específicos usados ​​para instanciar-lo. Após instanciação, o código resultante é equivalente ao código escrito especificamente para os argumentos passados. Deste modo, modelos de proporcionar uma forma de dissociar os aspectos genéricos, amplamente aplicáveis ​​de funções e classes (codificados em modelos) de aspectos específicos (codificados em parâmetros de modelo) sem sacrificar o desempenho devido à captação.

objetos

C ++ introduz programação orientada para o objecto (OOP) apresenta a C. Ele oferece as classes , os quais fornecem os quatro características normalmente presentes em OOP (e alguns não-OOP) idiomas: abstracção , encapsulamento , herança e polimorfismo . Uma característica distintiva de classes C ++ em comparação com aulas em outras linguagens de programação é o suporte para determinísticos destruidores , que por sua vez fornecem suporte para a aquisição de recurso é inicialização conceito (RAII).

encapsulamento

Encapsulamento é a ocultação de informações para garantir que as estruturas de dados e operadores são usados como pretendido e para tornar o modelo de uso mais óbvio para o desenvolvedor. C ++ fornece a capacidade de definir classes e funções como os seus mecanismos de encapsulamento primárias. Dentro de uma classe, os membros podem ser declarados como quer pública, protegida ou privada para impor explicitamente encapsulamento. Um membro público da classe é acessível para qualquer função. Um membro privado é acessível apenas para funções que são membros dessa classe e de funções e classes permissão de acesso explicitamente concedido pela classe ( "amigos"). Um membro protegido é acessível a membros de classes que herdam a classe, além da própria classe e todos os amigos.

O princípio orientada a objectos assegura o encapsulamento de toda e apenas as funções que o acesso a representação interna de um tipo. C ++ suporta este princípio através de funções de membro e funções amigo, mas não aplicá-la. Os programadores podem declarar partes ou a totalidade da representação de um tipo de ser público, e eles estão autorizados a fazer entidades públicas que não fazem parte da representação de um tipo. Programação, portanto, C ++ suporta não apenas orientado a objetos, mas outros paradigmas de decomposição, como programação modular .

É geralmente considerada uma boa prática para fazer todos os dados privada ou protegida, e para tornar públicas apenas as funções que fazem parte de uma interface mínima para os usuários da classe. Isso pode esconder os detalhes de implementação de dados, permitindo que o designer alterar posteriormente fundamentalmente a implementação sem alterar a interface de qualquer forma.

Herança

Herança permite que um tipo de dados para adquirir propriedades de outros tipos de dados. Herança de uma classe base pode ser declarado como público, protegido ou privado. Este especificador de acesso determina se as classes não relacionados e derivados pode acessar os membros públicos e protegidos herdados da classe base. Apenas herança pública corresponde ao que é geralmente entende por "herança". As outras duas formas são muito menos frequentemente utilizado. Se o especificador de acesso é omitido, uma "classe" herda privada, enquanto um "struct" herda publicamente. Classes de base pode ser declarado como virtual; isso é chamado de herança virtual . Herança virtual garante que apenas um exemplo de uma classe de base existe no gráfico de herança, evitar alguns dos problemas de ambiguidade de herança múltipla.

Herança múltipla é um C ++ característica não encontrada na maioria dos outros idiomas, permitindo uma classe a ser derivada da classe mais do que uma base; isso permite relações de herança mais elaborados. Por exemplo, uma classe "Flying Cat" pode herdar de ambos "Gato" e "Voar Mamífero". Algumas outras linguagens, como C # ou Java , realizar algo semelhante (embora mais limitado), permitindo que a herança de múltiplas interfaces de ao restringir o número de classes de base para um (interfaces de, ao contrário de aulas, fornecer apenas declarações de funções de membro, nenhuma implementação ou membro dados). Uma interface como em C # e Java pode ser definida em C ++ como uma classe única contendo funções virtuais puros, frequentemente conhecidos como uma classe base sumário ou "ABC". As funções de membro de uma tal classe base resumo são normalmente explicitamente definido na classe derivada, não herdado implicitamente. Herança virtual C ++ exibe um recurso de resolução ambigüidade chamado dominância .

Operadores e sobrecarga de operadores

Operadores que não podem ser sobrecarregadas
Operador Símbolo
operador de resolução de escopo ::
operador condicional ?:
operador ponto .
operador de seleção de membro .*
operador "sizeof" sizeof
operador "typeid" typeid

C ++ fornece mais de 35 operadores, cobrindo a aritmética básica, a manipulação de bits, indirecta, comparações, operações lógicas e outros. Quase todos os operadores pode ser sobrecarregado para tipos definidos pelo utilizador, com poucas excepções notáveis, tais como o acesso de membros ( .e .*), bem como o operador condicional. O rico conjunto de operadores Sobrecarregáveis é central para fazer tipos definidos pelo usuário em C ++ parecer tipos built-in.

Operadores Sobrecarregáveis também são uma parte essencial de muitas técnicas avançadas de programação C ++, como ponteiros inteligentes . Sobrecarregar um operador não altera a precedência de cálculos envolvendo o operador, nem alterar o número de operandos que os usos do operador (qualquer operando pode no entanto ser ignorados pelo operador, embora serão avaliados antes da execução). Sobrecarregado " &&" e " ||" operadores perder o seu curto-circuito avaliação propriedade.

Polimorfismo

Polimorfismo permite uma interface comum para muitas implementações, e para objetos a agir de forma diferente em diferentes circunstâncias.

C ++ suporta vários tipos de estática (resolvidas em tempo de compilação ) e dinâmica (resolvidas em run-time ) polimorfismos , apoiados pelos recursos de linguagem descritos acima. Em tempo de compilação polimorfismo não permite certas decisões de tempo de execução, enquanto o polimorfismo em tempo de execução tipicamente incorre em uma penalidade de desempenho.

polimorfismo estático

Sobrecarga de funções permite que os programas para declarar múltiplas funções com o mesmo nome, mas com argumentos diferentes (ie ad hoc polimorfismo ). As funções são distinguidos pelo número ou tipos de seus parâmetros formais . Assim, o mesmo nome de função pode referir-se a diferentes funções, dependendo do contexto em que é usada. O tipo retornado pela função não é usado para distinguir funções sobrecarregadas e resultaria em uma mensagem de erro em tempo de compilação.

Quando declarar uma função, um programador pode especificar para um ou mais parâmetros um valor padrão . Isso permite que os parâmetros com defaults, opcionalmente, ser omitidos quando a função é chamada, caso em que serão utilizados os argumentos padrão. Quando uma função é chamada com menos argumentos do que há são parâmetros declarou, argumentos explícitos são compatíveis com os parâmetros na ordem da esquerda para a direita, com os parâmetros incomparáveis no final da lista de parâmetros está sendo atribuído seus argumentos padrão. Em muitos casos, especificando argumentos padrão em uma única declaração da função é preferível a fornecer definições de funções sobrecarregadas com diferentes números de parâmetros.

Modelos em C ++ fornecer um mecanismo sofisticado para escrever o código genérico, polimórfica (por exemplo, polimorfismo paramétrico ). Em particular, através do modelo padrão curiosamente recorrente , é possível implementar uma forma de polimorfismo estático que imita a sintaxe para substituir as funções virtuais. Como os modelos C ++ são do tipo-aware e Turing completo , eles também podem ser usados para deixar os condicionais recursiva compilador resolver e gerar programas substanciais através de modelo metaprogramming . Ao contrário de alguns opinião, código do modelo não irá gerar um código de volume após a compilação com os ajustes apropriados do compilador.

polimorfismo dinâmico

Herança

ponteiros variáveis ​​e as referências a um tipo de classe de base em C ++, também pode se referir a objectos de quaisquer classes de derivados desse tipo. Isso permite que matrizes e outros tipos de recipientes para armazenar ponteiros para objetos de diferentes tipos (referências não podem ser directamente realizada em recipientes). Isso permite que o polimorfismo dinâmico (run-time), onde os referidos objetos podem se comportar de forma diferente dependendo de seus tipos (reais, derivadas).

C ++ também fornece o dynamic_castoperador, que permite que o código de segurança tentar conversão de um objecto, por meio de uma base de referência / apontador, para um tipo mais derivados: downcasting . A tentativa é necessário porque muitas vezes não se sabe que tipo derivado é referenciado. ( Upcasting , a conversão para um tipo mais geral, pode ser sempre verificado / executada em tempo de compilação via static_cast, como classes ancestrais são especificados na interface do classe derivada, visível para todos os chamadores.) dynamic_castBaseia-se em informações de tipo de tempo de execução (RTTI), metadados no programa que permite diferenciar os tipos e seus relacionamentos. Se um dynamic_casta um ponteiro falhar, o resultado é a nullptrconstante, ao passo que se o destino é uma referência (que não pode ser nulo), o fundido inicia uma excepção. Objetos conhecidos para ser de um certo tipo derivado pode ser convertido para que, com static_cast, ignorando RTTI eo tempo de execução tipo de verificação segura de dynamic_cast, por isso deve ser usado apenas se o programador é muito confiante de que o elenco é, e sempre será, válido.

funções membro virtuais

Normalmente, quando uma função em uma classe derivada substitui uma função de uma classe de base, a função a ser chamada é determinado pelo tipo do objecto. Uma função dada é substituído quando não existe nenhuma diferença no número ou tipo de parâmetros entre dois ou mais definições desta função. Assim, no momento de compilação, pode não ser possível determinar o tipo de objecto e, por conseguinte, a função correcta para chamar, dada apenas um ponteiro de classe base; a decisão é, portanto, adiada até a execução. Isso é chamado de despacho dinâmico . Funções membro virtuais ou métodos permitem a aplicação mais específica da função a ser chamado, de acordo com o tipo efectivo de tempo de execução do objecto. Em implementações C ++, este é comumente feito usando tabelas de função virtual . Se o tipo de objeto é conhecido, isso pode ser contornado, antecedendo um nome de classe totalmente qualificado antes da chamada de função, mas em chamadas gerais para funções virtuais são resolvidos em tempo de execução.

Além das funções membro normal, sobrecargas de operador e destruidores pode ser virtual. Como regra geral, se qualquer função na classe é virtual, o destruidor deve ser assim. Como o tipo de um objeto em sua criação é conhecido em tempo de compilação, construtores, e por construtores de cópia de extensão, não pode ser virtual. No entanto pode surgir uma situação em que uma cópia de um objecto precisa de ser criado quando um apontador para um objecto derivado é transmitido como um apontador para um objecto de base. Em tal caso, uma solução comum é o de criar uma clone()função virtual (ou semelhante) que cria e retorna uma cópia da classe derivada quando chamado.

A função de membro também pode ser feita "puro virtual", anexando-o com = 0após o parêntese de fechamento e antes do ponto e vírgula. Uma classe que contém uma função virtual pura é chamado de uma classe abstrata . Objetos não podem ser criados a partir de uma classe abstrata; eles só podem ser derivadas de. Qualquer classe derivada herda a função virtual pura e deve fornecer uma definição não-puro-lo (e todas as outras funções virtuais puras) antes de objetos da classe derivada pode ser criado. Um programa que as tentativas para criar um objecto de uma classe com uma função de membro virtual pura ou função de membro virtual pura herdado é mal formado.

As expressões lambda

C ++ fornece suporte para funções anónimos , também conhecidos como expressões lambda, com a seguinte forma:

[capture](parameters) -> return_type { function_body }

A [capture]lista suporta a definição de fechamento . Tais expressões lambda são definidos na norma como adoçante para um sem nome objeto função . Um exemplo de função de lambda pode ser definido como se segue:

[](int x, int y) -> int { return x + y; }

Manipulação de exceção

A manipulação de exceção é usado para comunicar a existência de um problema de tempo de execução ou erro de onde foi detectada a onde o problema pode ser tratado. Ele permite que isso seja feito de uma maneira uniforme e separadamente do código principal, ao detectar todos os erros. Deve ocorrer um erro, uma exceção é lançada (elevado), que é então capturado pelo manipulador de exceção adequado mais próximo. A excepção faz com que o âmbito de aplicação de corrente a ser retirado, e também cada escopo externo (propagação) até um manipulador apropriado é encontrado, ligando por sua vez, os processos de destruição de quaisquer objectos nesses âmbitos encerrado. Ao mesmo tempo, uma exceção é apresentado como um objecto que transporta os dados acerca do problema detectado.

Note-se que muitos C ++ "estilos", como Google, proíbem o uso de exceções em programas em C ++, restringindo a linguagem desta forma.

O código causadores de excepção é colocado dentro de um trybloco. As excepções são tratadas em separado catchblocos (os manipuladores); cada trybloco pode ter várias rotinas de tratamento de excepção, como é visível no exemplo abaixo.

 1 #include <iostream>
 2 #include <vector>
 3 #include <stdexcept>
 4 
 5 int main() {
 6     try {
 7         std::vector<int> vec{3, 4, 3, 1};
 8         int i{vec.at(4)}; // Throws an exception, std::out_of_range (indexing for vec is from 0-3 not 1-4)
 9     }
10     // An exception handler, catches std::out_of_range, which is thrown by vec.at(4)
11     catch (std::out_of_range &e) {
12         std::cerr << "Accessing a non-existent element: " << e.what() << '\n';
13     }
14     // To catch any other standard library exceptions (they derive from std::exception)
15     catch (std::exception &e) {
16         std::cerr << "Exception thrown: " << e.what() << '\n';
17     }
18     // Catch any unrecognised exceptions (i.e. those which don't derive from std::exception)
19     catch (...) {
20         std::cerr << "Some fatal error\n";
21     }
22 }

Também é possível gerar exceções propositadamente, usando a throwpalavra-chave; essas exceções são tratadas da forma habitual. Em alguns casos, as exceções não podem ser utilizados devido a razões técnicas. Um tal exemplo é um componente crítico de um sistema embarcado, em que cada operação deve ser garantida para completar dentro de um período de tempo especificado. Isso não pode ser determinado com exceções como não existem ferramentas para determinar o tempo máximo necessário para uma exceção a ser tratada.

biblioteca padrão

O C ++ padrão consiste de duas partes: o núcleo da linguagem e da biblioteca padrão. Programadores C ++ esperar o último em todas as principais implementação de C ++; que inclui tipos de agregados ( vetores , listas, mapas, jogos, filas, pilhas, matrizes, tuplas), algoritmos (encontrar, for_each, binary_search, random_shuffle, etc.), de entrada / saída (instalações iostream , de leitura e gravação para o console e arquivos), biblioteca de sistema de arquivos, suporte de localização, ponteiros inteligentes para o gerenciamento automático de memória, expressão regular de apoio, de multi-threading biblioteca, apoio atomics (permitindo uma variável a ser lido ou escrito por no máximo um segmento em um tempo sem qualquer externa sincronização), utilitários de tempo (medição, ficando hora atual, etc.), um sistema para converter o relatório de erros que não usa C ++ exceções em exceções C ++, um gerador de números aleatórios e uma versão ligeiramente modificada da biblioteca padrão C (para fazer Está de acordo com o sistema de tipo C ++).

Uma grande parte da biblioteca C ++ é baseado no Standard Template Library (STL). Ferramentas úteis fornecidas pelo STL incluem recipientes como as colecções de objectos (tais como vectores e listas ), iterators que fornecem acesso à matriz semelhante a recipientes, e algoritmos que executam operações, tais como a pesquisa e triagem.

Além disso, (multi) Mapas ( arrays associativos ) e (multi) conjuntos são fornecidos, os quais interfaces de exportação compatíveis. Portanto, o uso de modelos é possível escrever algoritmos genéricos que funcionam com qualquer recipiente ou em qualquer seqüência definida por iteradores. Como em C, as características da biblioteca são acedidos utilizando a #include directiva para incluir um cabeçalho padrão . A biblioteca C ++ padrão proporciona 105 cabeçalhos padrão, dos quais 27 são preteridos.

O padrão incorpora o STL que foi originalmente desenhado por Alexander Stepanov , que experimentou com algoritmos genéricos e recipientes para muitos anos. Quando ele começou com C ++, ele finalmente encontrou uma linguagem em que foi possível criar algoritmos genéricos (por exemplo, tipo STL) que executam ainda melhor do que, por exemplo, o C qsort biblioteca padrão, graças a C ++ recursos como a utilização de inlining e de compilação tempo de ligação em vez de ponteiros de função. A norma não se referem a ele como "STL", uma vez que é apenas uma parte da biblioteca padrão, mas o termo ainda é amplamente usado para distingui-lo do resto da biblioteca padrão (entrada / fluxos de saída, internacionalização, diagnósticos, o subconjunto biblioteca C, etc).

A maioria dos compiladores C ++ e todos os mais importantes, fornecer uma implementação normas conformes do ++ biblioteca padrão C.

Compatibilidade

Para dar compilador fornecedores de maior liberdade, o comitê de padrões C ++ decidiu não para ditar a implementação de deturpação nome , tratamento de exceções , e outras características específicas de implementação. A desvantagem desta situação é que decisão código de objecto produzido por diferentes compiladores se espera que seja incompatível. Não foram, no entanto, as tentativas para padronizar compiladores para máquinas particulares ou sistemas de operação (por exemplo, C ++ ABI), embora eles parecem estar largamente abandonado agora.

com C

C ++ é muitas vezes considerado um super conjunto de C , mas isso não é rigorosamente verdade. A maioria dos códigos C pode ser facilmente feito para compilar corretamente em C ++, mas existem algumas diferenças que fazem com que algum código C válido para ser inválido ou se comportar de maneira diferente em C ++. Por exemplo, C permite a conversão implícita a partir void*de outros tipos de ponteiro, mas não faz C ++ (por razões de segurança de tipo). Além disso, C ++ define muitas novas palavras-chave, tais como newe class, que podem ser usados como identificadores (por exemplo, nomes de variáveis) em um programa C.

Alguns incompatibilidades foram removidos pela revisão da norma C (1,999 C99 ), o qual suporta agora características C ++, tais como as observações de linha ( //) e declarações misturados com código. Por outro lado, C99 introduzido um certo número de características novas que C ++ não suportam eram incompatíveis ou redundante em C ++, tais como matrizes de comprimento variável , tipos dos números complexos nativos (no entanto, a std::complexclasse no C ++ biblioteca padrão proporciona uma funcionalidade semelhante, embora inicializadores não-código compatível), designado, literais compostos , e a restrictpalavra-chave. Algumas das características C99-introduzidas foram incluídos na versão subsequente do padrão C ++, C ++ 11 (fora das que não foram redundante). No entanto, o padrão C ++ 11 introduz novas incompatibilidades, como não permitir a atribuição de uma string literal para um ponteiro de caracteres, que continua válida C.

Para misturar C e código C ++, qualquer declaração de função ou definição que está a ser chamado de / utilizado tanto em C e C ++ deve ser declarada com ligação C, colocando-o dentro de um extern "C" {/*...*/}bloco. Tal função pode não depender de características, dependendo nome calandrar (isto é, função de sobrecarga).

Crítica

Apesar da sua adopção generalizada, alguns programadores notáveis têm criticado a linguagem C ++, inclusive Linus Torvalds , Richard Stallman , Joshua Bloch , Ken Thompson , e Donald Knuth .

Um dos pontos mais frequentemente criticado de C ++ é a sua percepção da complexidade como uma linguagem, com a crítica de que um grande número de recursos não-ortogonais, na prática necessita da restrição de código para subconjunto de C ++, evitando assim os benefícios de legibilidade do estilo comum e expressões idiomáticas. Como expresso por Joshua Bloch :

Eu acho que C ++ foi empurrado muito além do seu limite de complexidade e ainda há um grande número de pessoas programá-lo. Mas o que você faz é forçar as pessoas a subconjunto dele. Então, quase todas as lojas que eu conheço que usa C ++ diz: “Sim, estamos usando C ++, mas não estamos fazendo herança de múltipla aplicação e não estamos usando a sobrecarga de operador.” Há apenas um monte de recursos que você 'não vai usar, porque a complexidade do código resultante é muito alto. E eu não acho que é bom quando você tem que começar a fazer isso. Você perde essa portabilidade programador onde todos podem ler o código de todos os outros, o que eu acho que é uma coisa tão boa.

Donald Knuth (1993, comentando C pré-padronizado ++), que disse de Edsger Dijkstra que "pensar em programação em C ++" "faria dele fisicamente doente":

O problema que eu tenho com eles hoje é que ... C ++ é muito complicado. No momento, é impossível para mim escrever código portátil que eu acredito que iria trabalhar em muitos sistemas diferentes, a menos que eu evitar todas as características exóticas. Sempre que os ++ projetistas da linguagem C tinha duas ideias concorrentes a respeito de como eles devem resolver algum problema, eles disseram: "OK, vamos fazer os dois". Assim, a linguagem é muito barroco para o meu gosto.

Ken Thompson , que era um colega de Stroustrup na Bell Labs, dá a sua avaliação:

Ele certamente tem seus pontos positivos. Mas, em geral eu acho que é uma má língua. Ele faz um monte de coisas meia bem e é apenas um monte de lixo de idéias que se excluem mutuamente. Todo mundo que conheço, seja pessoal ou corporativa, seleciona um subconjunto e estes subconjuntos são diferentes. Portanto, não é uma boa linguagem para transportar um algoritmo-a dizer: “Eu o escrevi; aqui, levá-la.”É demasiado grande, demasiado complexo. E é, obviamente, construído por um comitê . Stroustrup campanha por anos e anos e anos, muito além de qualquer tipo de contribuições técnicas que ele fez para a linguagem, para obtê-lo adotado e usado. E ele meio que correu todos os comitês de padronização com um chicote e uma cadeira. E ele disse “não” a ninguém. Ele colocou todos os recursos nessa língua que já existiu. Não foi limpa-concebidas que era apenas a união de tudo que veio junto. E eu acho que sofreu drasticamente com isso.

No entanto Brian Kernighan , também um colega nos Laboratórios Bell, contesta essa avaliação:

C ++ tem sido extremamente influente. ... Muitas pessoas dizem C ++ é muito grande e muito complicado etc. etc. mas na verdade ele é uma linguagem muito poderosa e praticamente tudo o que está lá está lá por uma razão muito boa: não é alguém fazendo invenção aleatório , é, na verdade, pessoas tentando resolver problemas do mundo real. Agora um monte de programas que nós tomamos para concedido hoje, que acabamos de usar, são programas em C ++.

Stroustrup se comenta que: "dentro C ++, há uma linguagem muito menor e mais limpo lutando para sair".

Outras queixas podem incluir uma falta de reflexão ou coleta de lixo , os tempos de compilação lentas, percebida fluência característica , e mensagens de erro detalhado, particularmente de modelo metaprogramming.

Veja também

Referências

Outras leituras

links externos

  • JTC1 / SC22 / WG21  - o Grupo de Trabalho Padrão ++ ISO / IEC C
  • Fundação ++ C padrão  - uma organização sem fins lucrativos que promove o uso e compreensão do padrão C ++. Bjarne Stroustrup é um diretor da organização.