# Programar em C++/Introdução
## Pensando no código

Considerando o conjunto de operações e eventos que nosso programa deve executar temos diversas maneiras de criar o código, porém o mais difícil é criar um código eficiente, rápido e compacto. Na verdade, diversos fatores podem interferir nestes aspectos da programação, entre eles, a escolha do compilador, o método de estruturar o código, a orientação do mesmo, etc... Em termos gerais, um código torna-se mais próximo do ideal a medida que suas partes tornam-se mais simples de se analisar e quando todos os processos estão bem definidos e especializados. Quando temos um código que contém muito mais exceções do que regras, este precisa de uma reestruturação.
Podemos definir C++ como um "superconjunto" da linguagem C, ou seja, uma linguagem com mais funcionalidades que a linguagem C. Embora este seja o ponto de vista de quem já tem um conhecimento da linguagem C, ela é muito mais que isto. Podemos mudar completamente a forma de criar o programa quando usamos os recursos avançados da linguagem, as estruturas de decisão (por exemplo, if-else ou switch) podem ser simplificadas e a organização do código pode ser bem mais globalizada e genérica, possibilitando a reutilização do código em diversas situações diferentes.
Vejamos como as funcionalidades da linguagem C++ podem ajudar a redefinir os meios de programação que aprendemos com o bom e velho estilo C.

## Dois modos de programar

Observando o modo de programar que as linguagens oferecem desde os primórdios da computação, podemos notar vários métodos que foram sendo superados e outros que se estabelecem por um momento. O modo de programar mais usual e bem mais difundido é conhecido como modelo estruturado sequencial. Em síntese, refere-se a forma de programar onde uma instrução segue a outra numa sequência que inicia e termina em um fluxo parcialmente "previsível".
A programação estruturada ainda pode ser classificada em dois modos: um orientado a procedimentos e outro orientado a objetos. Os dois podem ser confundidos por quem não tem muita experiência, mas o uso de um ou do outro implica em características próprias para cada caso. Logo, é preciso entender bem os conceitos antes de definir se um código é procedural ou orientado a objetos.
O modelo sequenciado procedural é bem simples de implementar, porém, aumenta a complexidade para tarefas mais bem trabalhadas e sofisticadas. Isto ocorre devido a estrutura do modelo, que exige rotinas cada vez mais extensas. Não raramente é possível encontrar rotinas que, em alguns casos, tornam-se comparáveis a programas completos, usando como referência o número de linhas de instruções. O uso deste modelo, muitas vezes dificulta a manutenção e expansão do código, caso isto não seja feito de maneira muito bem organizada.
O segundo modelo é o orientado a objetos. O que significa isso e o que muda no modo de programar, caso o adotemos em vez do modelo anterior?
A orientação define o modo de abordar o problema para tentar solucioná-lo:
* O modelo de orientação a procedimentos se preocupa em fornecer meios para resolver o problema sem contabilizar, a princípio, os dados que serão usados durante o processo.
* O modelo de orientação a objetos se preocupa com os elementos que são necessários para a solução de um problema. Sob este ângulo, os dados são os elementos principais na análise do problema.
Este livro traz uma visão dos problemas sob a óptica da orientação a objetos, enquanto que o livro "Programar em C" traz a análise sob a óptica da orientação a procedimentos. Isto não quer dizer que devamos escolher a orientação a objetos como o modo mandatório de programação, mas que podemos contar com seus recursos sempre que esta escolha facilite a resolução do problema. Portanto, cabe sempre uma análise para definir se o problema é melhor tratado por uma abordagem orientada a objetos ou a procedimentos.

## Um pouco sobre orientação a objetos

A programação orientada a objetos é um paradigma de programação que visa organização, produtividade e sustentabilidade.
A apresentação dos conceitos de orientação a objetos é bastante abrangente, o que implica na abordagem de diversos aspectos, como modelagem, estudo de performance de modelos, aplicabilidade de técnicas, estruturação de objetos, otimização, manutenção do código, entre outros. Por este motivo, nosso objetivo aqui não é apresentar a orientação a objetos em sua totalidade. Para um estudo mais detalhado do tema sugerimos o livro POO, que trata especificamente deste tema. O objetivo aqui é apresentar como a orientação a objetos se aplica na linguagem C++, porém os conceitos aqui apresentados devem ser suficientes para a estruturação de programas de bom nível.
A ideia principal por trás do modelo de programação orientado a objetos está em transformar entidades do mundo real em identificadores dentro do programa (objetos), trabalhando-os como entidades da linguagem que possuem características e operações próprias. Esta abordagem transforma o programa em um meio de simulação de situações virtuais por meio de entidades de código que têm comportamento predefinido. Esta abstração é uma aliada do programador por permitir idealizar sistemas mais sofisticados de uma maneira bastante intuitiva.
Todas as linguagens orientadas a objetos contêm os princípios de:
* Encapsulamento
    É um mecanismo para esconder os detalhes envolvidos no processamento de uma ação. Por exemplo, quando usamos um telefone, não precisamos lidar diretamente com o circuito interno; a interface do telefone cuida desse problema.
* Polimorfismo
    Isso permite o uso de uma única interface ― uma única forma de uso ― para objetos de tipos diferentes; em particular, a mesma interface para objetos de uma classe e objetos de classes derivadas dessa.
* Herança
    Como o nome sugere, isso permite que uma classe herde de outra suas características, podendo também introduzir suas próprias ou alterar as características herdadas. O uso de herança acaba poupando trabalho e melhorando a organização do código.

### Paradigmas da Programação:

Desde o início da programação, já passamos pelos seguintes paradigmas:
* Não estruturada - exemplos: COBOL, FORTRAN, BASIC (anos 50-60)
* Procedimental ou Procedural - exemplos: C, Pascal (anos 70)
* Modular - exemplo: Modula II (anos 80)
* Abstração de tipos de dados - exemplo: Ada (anos 80)
* Programação Orientada a Objetos - exemplos: C++, Java, Delphi (Object Pascal) entre outras. (décadas 80-90-2000)

## Objetos

Objeto é, genericamente, uma entidade de armazenamento e manipulação de dados. O mesmo deve ser criado para processar os dados que armazena e recebe, sendo sensível a entradas do programa principal para fornecer as saídas esperadas pelo mesmo. Por estes motivos o objeto deve ser pensado como uma entidade de dados autônoma, encarregada de processar todos os dados que mantém.
Da mesma forma que podemos usar tipos de dados nativos da linguagem podemos criar nossos tipos de dados. Na linguagem C podemos criar tipos de dados compostos que chamamos de estruturas, estes são criados com a palavra chave struct. C++ possibilita o uso de estruturas de dados e introduz um novo tipo chamado de classe. Como o nome sugere, uma classe refere-se a um conjunto de características dadas a um grupo de "indivíduos", ou seja, grupo de objetos. Por este motivo, classe é a definição de tipo de objeto.
Em C++ as classes de objetos são criadas através da palavra chave class. Esta nomenclatura é usada por muitas outras linguagens de programação mais caracteristicamente restritas a orientação a objetos. Estes aspectos facilitam um pouco o aprendizado por programadores já familiarizados com estas linguagens quando iniciam a programação em C++.
O processo de criação de um objeto segue a sequência:
* Definir os dados e procedimentos que a classe deve conter;
* Criar a classe de objetos;
* Declarar (instanciar) o objeto.
A definição de uma classe de objetos deve ser feita de forma a tornar, preferencialmente, todos os dados protegidos de interferências de códigos externos ao objeto. Por este motivo um objeto deve ser uma parte do código do programa com uma certa autonomia. Este deve ter controle sobre seus dados e ser capaz de provê-los e lidar com eventos a eles relacionados. Dentro de seu escopo de responsabilidades, a entidade deve essencialmente "ter vida própria".