Programar em C++
141 pág.

Programar em C++


DisciplinaLinguagem de Programação Estruturada128 materiais1.055 seguidores
Pré-visualização34 páginas
operações de manipulação destes dados. Uma das vantagens deste procedimento é
que o código adquire um formato mais organizado, onde os processos tornam-se claramente distintos, caso tenhamos
que analisar o código, cada procedimento estará restrito a partes definidas para cada operação.
Declarando classes
As estruturas são bem parecidas com as classes, com uma pequena diferença, peguemos o caso da passagem de
estruturas como argumentos de funções:
#include <iostream>
#include <string>
#ifndef WIN32 //No caso de não estar programando em Windows
 #include <conio.h> //será incluída a biblioteca conio.h
#endif //que possibilita usar getch(); em vez de system(&quot;PAUSE&quot;);
 using namespace std;
 class Person 
 {
 string name; 
 int height;
 };
 void setValues(Person&);
 void getValues(const Person&);
 int main ()
 {
 Person p1;
 setValues(p1); 
 cout << &quot;Informando dados sobre a pessoa:\n&quot;;
 cout << &quot;================================\n&quot;;
 getValues(p1);
#ifdef WIN32
 system (&quot;pause&quot;);
#else
 getch();
#endif
 return 0;
 }
 void setValues(Person& pers)
 {
 cout << &quot;Informe o nome da pessoa: &quot;;
 getline(cin, pers.name);
Classes 84
 cout << &quot;Informe a altura em milímetros: &quot;;
 cin >> pers.height; 
 cin.ignore();
 }
 void getValues(const Person& pers)
 {
 cout << &quot;Nome da pessoa: &quot; << pers.name << endl; 
 cout << &quot;A altura da pessoa em milímetros é: &quot; << pers.height << endl;
 }
\u2022 Mudamos o identificador de struct para class
\u2022\u2022 Mas se tentarmos compilar o programa isto vai causar erros de compilação, porque agora temos variáveis membro
que são privadas por padrão, estas não são vistas por funções fora da classe.
Dentro de uma classe podemos definir diversos modos de visibilidade de variáveis e funções.
As modalidades podem ser:
\u2022 private (só podem ser acessados por membros da mesma classe)
\u2022 public (pode ser acessadas fora do objeto, onde este estiver definido)
\u2022 protected (deixemos esta para quando falarmos em classes derivadas, pois depende deste conceito).
Ora, como as funções getValues e setValues não são membros da classe Person, tal como o construtor Person, não
conseguem acessar as variáveis &quot;name&quot; e &quot;height&quot;.
Visualizamos melhor em forma de tabela:
Class Person private
string name
Int height
p1
A solução é criar funções publicas, para ler de e escrever para as variáveis privadas:
 #include <iostream>
 #include <string>
 using namespace std;
 class Person 
 {
 private:
 string name; 
 int height; 
 public:
 string getName() const;
 void setName(string);
 int getHeight() const;
 void setHeight(int);
 };
Classes 85
 string Person::getName() const
 { return name; }
 void Person::setName(string s)
 { 
 if (s.length() == 0)
 name = &quot;No name assigned&quot;;
 else
 name = s; 
 }
 int Person::getHeight() const
 { return height; }
 void Person::setHeight(int h)
 { 
 if (h < 0)
 height = 0;
 else
 height = h; 
 }
 void setValues(Person&);
 void getValues(const Person&);
 int main ()
 {
 Person p1;
 setValues(p1); 
 cout << &quot;Outputting person data\n&quot;;
 cout << &quot;======================\n&quot;;
 getValues(p1);
 return 0;
 }
 void setValues(Person& pers)
 {
 string str;
 int h;
 cout << &quot;Enter person's name: &quot;;
 getline(cin,str);
 pers.setName(str);
 cout << &quot;Enter height in milimeters: &quot;;
 cin >> h;
 cin.ignore();
 pers.setHeight(h);
 }
Classes 86
 void getValues(const Person& pers)
 {
 cout << &quot;Person's name: &quot; << pers.getName() << endl; 
 cout << &quot;Person's height in milimeters is: &quot; << pers.getHeight() << endl; 
 }
Mas perguntam: Por que é que nos demos ao trabalho de recorrer a membros privados em vez de fazer todos
públicos? Quando tínhamos uma estrutura no lugar de uma classe, não havia nada que impedisse a colocação de
valores inválidos, por isso poderíamos ter valores vazios para a string e valores negativos para a variável &quot;height&quot;.
Agora que &quot;Person&quot; é uma classe, as funções membro podem realizar a validação dos dados antes da atribuição de
valores nas variáveis. Poderíamos fazer com que a função setName verificasse se a entrada na string seria vazia e
caso fosse, colocaria um valor padrão como: \u201csem nome\u201d. similarmente poderíamos ter &quot;setHeight&quot; para verificar se
seriam colocados valores de entrada negativos e caso fossem, colocaria zero, ou não tomaria nenhuma ação.
Todas estas características demonstram o conceito de encapsulamento. A sua finalidade é de tornar o código mais
modularizado, restringindo o escopo de análise a partes bem delimitadas dos programas. Devido a este conceito
podemos contar com códigos mais fáceis de analisar e fazer manutenção.
Instanciando objetos
Instanciação de objetos é o processo de criar a estrutura lógica dos mesmos na memória. Isto ocorre quando
declaramos os objetos, pois neste momento todo o processo de construção dos mesmos é efetivado. Assim, toda vez
que declaramos um objeto estamos instanciando-o, ou seja, estamos criando uma instância da classe.
Podemos declarar os objetos logo após definir a classe conforme podemos ver no 1º caso logo abaixo. Neste caso
teremos a variável rect criada como um objeto conforme estabelecido pelo modelo definido pela palavra chave class.
Este tipo de declaração é mais usual para objetos criados globalmente, pois a inclusão desta declaração no cabeçalho
pode fazer com que vários objetos sejam criados com o mesmo nome quando o cabeçalho é invocado de vários
arquivos. Portanto, é mais prudente usar esta opção quando a declaração está no arquivo fonte e não no cabeçalho.
1º caso:
 class CRectangle 
 {
 int x, y;
 public:
 void set_values (int,int);
 int area (void);
 } rect; 
No 2º caso, apresentado logo abaixo, podemos declarar objetos apenas quando precisarmos. Esta opção de declarar o
objeto depois é a mais usada, pois na maioria das vezes temos o modelo dos objetos, a classe, declarada em um
arquivo de cabeçalho enquanto que os objetos serão criados no resto do código fonte. Desta forma é mais usual criar
as classes em cabeçalhos e depois declarar os objetos na parte do programa que for mais conveniente.
2º caso:
class CRectangle 
 {
 int x, y;
 public:
 void set_values (int,int);
Classes 87
 int area (void);
 };
 int main()
 {
 CRectangle rect;
 }
Em ambos os casos temos
CRectangle Private public
int x
int y
void set_values (int,int);
int area (void);
rect
Podemos, então, entender os objetos como blocos de dados que têm propriedades (variáveis) e que podem fazer algo
(métodos). Então, criamos todas as funcionalidades que precisamos que a classe forneça aos programas, fazendo os
testes necessários para assegurar sua consistência e estabilidade. Sempre que precisemos utilizar os objetos só temos
que instanciá-los (declará-los), e não precisamos nos preocupar como eles funcionam internamente, uma vez que os
desenhamos adequadamente.
Para entendermos melhor este conceito podemos fazer uma analogia. Consideremos um objeto resistência: sabemos
que temos de usá-lo e que ela deve ter certas características, então teremos o seu valor em Ohms, sua potência
máxima, tolerância, entre outras, e teremos uma função que nos dará a corrente que passa por ela quando lhe
aplicamos uma tensão elétrica. Não precisamos saber de que é que ela é feita, ou como estas características internas a
faz funcionar, basta-nos receber os resultados.
Vejamos o exemplo:
Agora vamos mostrar que podemos ter funções membro apenas como protótipos e defini-las fora da classe. Para isso
usamos o operador