Esta apresentação ensinará os conceitos de Orientação a Objetos com C++, do mais básico para o mais avançado. É suposto que o aluno já tenha

Documentos relacionados
Na disciplina de Cálculo Numérico, vamos trabalhar com a linguagem C++ e o compilador que vamos usar é o Dev C++.

Orientação a Objetos

Computação II Orientação a Objetos

Aula 1 Tipo Abstrato de Dados

INTRODUÇÃO AO C++ SISTEMAS DE INFORMAÇÃO DR. EDNALDO B. PIZZOLATO

Implementando uma Classe e Criando Objetos a partir dela

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Linguagem de Programação III

Introdução a POO. Introdução a Linguagem C++ e POO

Componentes da linguagem C++

Prof. Jhonatan Fernando

Programação Orientada a Objetos em Java

POO Programação Orientada a Objetos. Classes em Java

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br

EXERCÍCIOS SOBRE ORIENTAÇÃO A OBJETOS

Introdução. Manipulação de arquivos em C. Estrutura de Dados II Prof Jairo Francisco de Souza

Programação Orientada a Objetos C++

O que é um algoritmo? O que é um programa? Algoritmos. Programas. Aula 1 Tipo Abstrato de Dados

Introdução a Java. Hélder Nunes

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA INFORMÁTICA APLICADA

ARRAYS. Um array é um OBJETO que referencia (aponta) mais de um objeto ou armazena mais de um dado primitivo.

ATRIBUTOS PRIVADOS 6. ENCAPSULAMENTO MÉTODOS PRIVADOS MÉTODOS PRIVADOS

Pilhas. Profa Morganna Diniz

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C / C++

3 Classes e instanciação de objectos (em Java)

Profº. Enrique Pimentel Leite de Oliveira

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

Programação Orientada a Objetos - 3º semestre AULA 08 Prof. André Moraes

Noções sobre Objetos e Classes

A Introdução à Programação Orientada a Objetos. Programação e Sistemas de Informação

Programação Estruturada e Orientada a Objetos. Fundamentos Orientação a Objetos

Programação de Computadores - I. Profª Beatriz Profº Israel

Programação Orientada a Objetos Classes Abstratas Técnico em Informática. Prof. Marcos André Pisching, M.Sc.

AULA 4 VISÃO BÁSICA DE CLASSES EM PHP

Curso de Linguagem C

Lógica de Programação

INTRODUÇÃO AO JAVA PARA PROGRAMADORES C

Linguagem de Programação III

2 Orientação a objetos na prática

CONVENÇÃO DE CÓDIGO JAVA

JSP - ORIENTADO A OBJETOS

Exercício 1 : As classes abaixo serão utilizadas neste exercício: public class Ponto { int x; int y; public Ponto(int x, int y){ this.

Java 2 Standard Edition Como criar classes e objetos

Aula 1. // exemplo1.cpp /* Incluímos a biblioteca C++ padrão de entrada e saída */ #include <iostream>

Objetivos: Sun recomenda que utilize o nome de domínio da Internet da empresa, para garantir um nome de pacote único

Estrutura da linguagem de programação C Prof. Tiago Eugenio de Melo tiago@comunidadesol.org

OO Engenharia Eletrônica

Programação Orientada a Objetos em Java. Herança

Computação e Programação Aula prática nº 5. Enunciados dos problemas

Unidade Acadêmica: Faculdade de Computação FACOM Disciplina: Programação Orientada a Objetos I Professor: Fabiano Azevedo Dorça Prática 01

Desenvolvimento OO com Java Orientação a objetos básica

NetBeans. Conhecendo um pouco da IDE

Programação científica C++

DEFINIÇÃO DE MÉTODOS

Programação por Objectos. Java

Curso de PHP. FATEC - Jundiaí. A programação orientada a objetos (object-oriented oriented programming

Tabelas (arrays) (vetores, matrizes, etc) Algoritmos de pesquisa Algoritmos de ordenação

STL significa Standard Template Library. É uma biblioteca que contém algumas estruturas de dados, como árvore binária e lista encadeada.

Um objeto é uma instância de uma 'classe'. Você define uma classe utilizando o trecho de código abaixo;

CAPÍTULO 3 - TIPOS DE DADOS E IDENTIFICADORES

5 - Vetores e Matrizes Linguagem C CAPÍTULO 5 VETORES E MATRIZES

17 - Funções e Procedimentos em C Programação Modular

NOVIDADES DO JAVA PARA PROGRAMADORES C

Engenharia de Software III

Conceitos básicos da linguagem C

Curso: Desenvolvendo Jogos 2d Com C# E Microsoft XNA. Mostrar como funciona a programação orientada a objetos

Programação por Objectos. Java

Programação Orientada a Objetos Prof. Rone Ilídio UFSJ/CAP

Curso de Java. Orientação a objetos e a Linguagem JAVA. TodososdireitosreservadosKlais

Persistência de Dados

Para criar uma animação precisamos de uma imagem e que ela contenha alguns frames. O número de frames é uma escolha sua.

Prof. Esp. Adriano Carvalho

Conceito de classe em C++

2 Desenvolvimento de Software Orientado a Aspectos

OPERADORES E ESTRUTURAS DE CONTROLE

Programação com Acesso a BD. Programação com OO Acesso em Java

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO)

PROGRAMAÇÃO II 4. ÁRVORE

Fundamentos de Programação

Templates e Pilhas. 1. Introdução

9 Comandos condicionais

Busca. Pesquisa sequencial

struct LISTA item quant

1 Funções básicas de implementação de arquivos

Membros de classe e de instância. PARTE III: Java e OO - detalhes. Exemplo 1: método. Exercício. Exemplo 1 corrigido

RevISTa: Publicação técnico-científica do IST-Rio. nº 05 Data: Dezembro / 2012 ISSN

UNIVERSIDADE FEDERAL DO PARANÁ

Programação Orientada a Objeto

Dadas a base e a altura de um triangulo, determinar sua área.

Curso de Programação Computadores

JAVA NETBEANS PGOO Prof. Daniela Pires Conteúdo

Algoritmos e Programação

Programação Orientada a Objetos

2ª Lista de Exercícios

Padrões de Projeto. Singleton

Resumo da Matéria de Linguagem de Programação. Linguagem C

Transcrição:

Esta apresentação ensinará os conceitos de Orientação a Objetos com C++, do mais básico para o mais avançado. É suposto que o aluno já tenha conhecimento avançado de C.

Exemplo em C: Faça um programa que jogue dois dados e some os números que sairam. Ficaria assim: #include <stdio.h> #include <stdlib.h> #include <time.h> int main(int argc, char **argv) { short int dado1, dado2, soma; srand (time(null)); dado1 = (short int) (rand() % 6) + 1; dado2 = (short int) (rand() % 6) + 1; soma = dado1 + dado2; printf("%d\n", dado1); printf("%d\n", dado2); printf("%d\n", soma); return 0; Este programa funciona e faz o que foi pedido, mas... ele é organizado? Em um programa pequeno é aceitável fazer o código assim, mas e num projeto grande como um jogo, feito por mais de 15 pessoas? Os dados estão sendo representados por ints, e para sortear um número, repete-se a linha do rand() várias vezes. Usando OO, este problema da desorganização é resolvido. A partir do próximo slide, este código será transformado em C++ orientado a objetos.

Em C existe uma ferramenta chamada struct. Uma struct para representar um dado seria assim: typedef struct { int ultimo_valor_sorteado; Dado; Em C++, embora também seja possível fazer structs, há um irmão evoluido desta ferramenta: classes. Uma classe é como uma struct, mas que permite adição de funções além das váriaveis. Na verdade classes são muito mais complexas do que isso, como veremos mais a frente, mas esta comparação com struct não deixa de estar certa... Veja uma classe dado: class Dado { public: int valor; int sorteia(void) { return valor = (rand() % 6) + 1; Dado() { srand (time(null)); valor = 0; ;

#include <iostream> #include <time.h> using namespace std; class Dado { public: int valor; int sorteia(void) { return valor = (rand() % 6) + 1; Dado() { srand (time(null)); valor = 0; ; int main(int argc, char **argv) { Dado dado1,dado2; cout << dado1.sorteia() << endl; cout << dado2.sorteia() << endl; cout << dado1.valor + dado2.valor << endl; return 0; Assim, o código fica muito mais legível do que o outro em C. Os dados não são mais representados por ints: agora um dado é chamado exatamente de Dado. As váriaveis e contas, para não serem repetidas o tempo todo no código, estão dentro da classe. Querendo usar o valor sorteado, escreve-se x.valor, e para sortear, x.sorteia(). Cada dado terá armazenado o valor sorteado, e poderá ser jogado de novo. Esta prática organiza o código, diminui o número de linhas em projetos grandes e facilita o entendimento, pois os nomes de classes, variáveis e métodos são diretos. Detalhes ainda desconhecidos como o namespace e a função Dado() serão explicadas no futuro.

Construtores Antes de continuar, alguns detalhes de nomenclatura devem ser ditos. Variáveis dentro de classes são chamadas de atributos, e funções dentro de classes são chamadas de métodos. No exemplo anterior, um Dado possui o atributo valor e o método sortear. Atributos são os valores característicos de uma classe, e métodos são ações praticadas por ela. Não é mais lógico chamar assim? Havia no exemplo anterior um método Dado() dentro da classe Dado. Métodos com o mesmo nome da classe são chamados de métodos construtores. Eles são chamados quando a variável é criada. Ou seja, ao escrever a linha Dado dado1;, o método Dado() é chamado automaticamente. Significa que assim que d1 é criado, o seu atributo valor já é setado para zero. É possível criar também construtores que recebem parâmetros.

#include <iostream> using namespace std; class Pessoa { public: string nome; int idade; Pessoa(string nome, int idade):nome(nome), idade(idade) { ; int main (int argc, char **argv) { Pessoa p("joao",15); cout << p.nome << endl; cout << p.idade << endl; return 0; Exemplo de construtor recebendo parâmetros. Veja que a variável p, quando é criada, recebe valores por parênteses, uma string e um int. Estes valores são passados para o construtor e os atributos são inicializadas. Note que ao lado do construtor há dois pontos seguidos por: nome(nome), idade(idade). Este é um modo de inicializar as variáveis. idade(idade) significa: O atributo 'idade' receberá o valor do parâmetro 'int idade'. Escrito deste modo, ambos podem ter o mesmo nome que o compilador não se confundirá. Deste modo, o código não fica poluído com várias variáveis de nomes diferentes desnecessariamente.

Encapsulamento Em ambos os exemplos até agora foi cometido um erro proposital. Embora não pareça, os códigos de Dado e Pessoa estão com uma séria falha de segurança. Dado: Um dado foi arremessado com o método sortear(), e este valor sorteado foi armazenado no atributo 'valor'. Mas note que quem usar a classe Dado ainda será capaz de fazer, na main, x.valor = 7. Isto estragaria a lógica do programa, pois um dado (comum) não possui o valor 7. Pessoa: É possível entrar com o valor da idade da pessoa. O que acontece se for entrado o valor -1? Nada. Ou seja, outra falha. Para contornar estas falhas, existe o encapsulamento. Basta proibir o acesso a todos os atributos e tratar suas modificações através de métodos, chamados getters e setters.

#include <iostream> #include <time.h> using namespace std; class Dado { private: // Nada abaixo de private pode ser acessado fora da classe. int valor; // Como o que define o 'valor' é o sorteio, ela não pode nunca ser modificada. public: // Os métodos marcados como public são acessíveis fora da classe int sorteia(void) { return valor = (rand() % 6) + 1; int getvalor(void) { return valor; ; Dado() { srand (time(null)); valor = 0; int main(int argc, char **argv) { Dado dado1,dado2; // Tente modificar o valor da variável valor. Agora é impossível! cout << dado1.sorteia() << endl; cout << dado2.sorteia() << endl; cout << dado1.getvalor() + dado2.getvalor() << endl; return 0;

#include <iostream> using namespace std; class Pessoa { private: string nome; int idade; public: Pessoa(string nome, int idade):nome(nome) { setidade(idade); ; string getnome(void) { return nome; void setnome(string nome) { this->nome = nome; int getidade(void) { return idade; void setidade(int idade) { this->idade = idade < 0? -idade : idade; int main (int argc, char **argv) { Pessoa p("maria",-20); cout << p.getnome() << endl; cout << p.getidade() << endl; return 0; Deve-se sempre proibir o acesso a todos os atributos usando a palavra private, e liberar todo o resto com public. Os que não estiverem em um destes modificadores de acesso serão considerados private. Mesmo que a proibição em alguns casos pareça inútil, pode ser que venha a ser útil no futuro. Os métodos getx() e setx() servem para acessar e tratar os dados privados. Não esqueça de colocar estes métodos sempre como públicos. this->nome = nome; significa: O atributo nome desta classe recebe o valor da variável nome passada por parâmetro. É um outro artifício usado para economizar palavras. O outro é o nome(nome), usado no construtor. Deixe os atributos sempre private, mas faça getters e setters apenas se necessário. Note que não foi feito o método setvalor() no slide anterior.

Sobrecarga Em C++ (e em qualquer outra linguagem orientada a objetos, como Java), é possível criar mais de um método com o mesmo nome. Os métodos de mesmo nome são diferenciados pelos parâmetros: tipos, ordem e quantidade deles. É possível modificar a classe Dado adicionando os dois métodos: // Método que já existe na classe int sorteia(void) { return valor = (rand() % 6) + 1; // Supondo que o dado seja de vários lados int sorteia(int ordem) { return valor = (rand() % ordem) + 1; Os métodos possuem o mesmo nome, mas os parâmetros são diferentes. Tente você desta vez modificar a classe Dado :)

É possível também fazer sobrecarga de construtores. Ou seja, uma classe pode ter vários construtores, desde que seus atributos sejam capazes de diferenciá-los uns dos outros. A classe Pessoa possui um construtor que seta os valores do nome e da idade. É possível fazer, ao mesmo tempo, construtores assim: Pessoa(string nome, int idade) {... // Já existe na classe! Pessoa(string nome) {... // Inicia o valor do nome apenas. Pessoa(int idade) {... // Inicia o valor da idade apenas. Pessoa() {... // Não inicia nada. Apenas cria a pessoa. Tente fazer esta modificação na classe pessoa e veja que de fato é possível criar vários construtores por classe. Esta possibilidade de escrever um mesmo método de várias formas é chamado de sobrecarga.

Uso de Ponteiros Até agora não foi dada muita atenção, mas é preciso (e muito importante) diferenciar uma variável de um objeto. Fazendo Dado d1, é criado um objeto da classe Dado. Foi criada uma instância de Dado. Entenda classe como algo abstrato e generalizado, e objeto (ou instância) como algo concreto e único. Outro exemplo: Imagine que existe, no além, uma classe Pessoa, e que VOCÊ E EU somos instâncias desta classe :) É possível criar em C++ ponteiros para objetos. A linha Dado *d1 cria um objeto? A resposta é NÃO! Neste caso é criado apenas um ponteiro, que inicialmente aponta para NULL. Veja nos slides seguintes como usar ponteiros para objetos. Será apresentada a palavra new.

#include <iostream> using namespace std; // Esta classe representa uma coordenada. (x,y) class Ponto { private: int x, y; public: int getx(void) { return this->x; int gety(void) { return this->y; void setx(int x) { this->x = x; void sety(int y) { this->y = y; Ponto(int x, int y) : x(x), y(y) { Ponto(void) { this->x = this->y = 0; ; Continua no slide seguinte...

int main(int argc, char **argv) { // Ponteiro para Ponto. Ele está apontando, inicialmente, para NULL. Ponto *p1; // Está sendo criado um ponteiro chamado p2. p2 APONTA para um objeto, // criado com a palavra 'new'. // O objeto não possui um nome. Sabe-se apenas que p2 aponta para ele. Ponto *p2 = new Ponto; // O mesmo caso acima, mas desta vez, foi usado outro construtor. Ponto *p3 = new Ponto(9,15); // Aloca espaço para um ponto, mas nenhum construtor é chamado. Ponto *p4 = (Ponto*) (malloc(sizeof(ponto))); // Objetos criados diretamente. Ponto p5; Ponto p6(2,5); // Para buscar um atributo ou método através de um ponteiro, usa-se uma seta. cout << p3->getx() << endl; // E para buscar de um objeto criado diretamente, usa-se um ponto. cout << p6.gety() << endl; return 0;

Destrutores Objetos podem ser construídos e também destruídos. Um objeto deve ser destruído quando não for mais utilizado. Esta destruição é feita através do método destrutor. Objetos criados diretamente, sem ponteiros, são destruídos automaticamente ao fim do código. Os objetos instanciados a partir de ponteiros (com a palavra new) não são destruidos automaticamente, apenas o programador pode fazê-lo. Métodos construtores são similares ao free(), de C. Os dois desalocam espaço de um ponteiro. É uma boa prática (essencial em projetos grandes) destruir todos os objetos que não forem mais utilizados. Em algumas linguagens isso é feito automaticamente. Toda classe já possui um destrutor padrão, que desaloca um ponteiro. Mas é possível escrever um método destrutor, para executar alguma ação específica. Ao escrever um novo destrutor, estamos substituindo o padrão por este novo método. Métodos destrutores são escritos com o mesmo nome da classe, e com um ~(til) antes do nome. Um ponteiro é desalocado através da palavra delete.

#include <iostream> using namespace std; class Ponto { private: int x, y; public: int getx(void) { return this->x; int gety(void) { return this->y; void setx(int x) { this->x = x; void sety(int y) { this->y = y; Ponto(int x, int y) : x(x), y(y) { Ponto(void) { this->x = this->y = 0; ~Ponto(void) { // "cout" apenas para que seja visível // a destruição na compilação :) cout << "BUM!" << endl; ; int main(int argc, char **argv) { Ponto *p1; Ponto *p2 = new Ponto; Ponto *p3 = new Ponto(9,15); Ponto *p4 = (Ponto*) (malloc(sizeof(ponto))); Ponto p5; Ponto p6(2,5); delete p4; // Compile e veja que o destrutor será chamado 3 vezes. // Foram destruidos p4, p5 e p6. return 0;

O operador :: As classes feitas até agora (Dado, Pessoa e Ponto) foram feitos de modo correto, mas não do modo padrão de C++. Em C, as funções presentes no programa têm seus cabeçalhos declarados no início do código. Estes cabeçalhos são chamados protótipos das funções. As classes devem ser apenas o conjunto de protótipos dos métodos. Estes devem ser declarados do lado de fora da classe. A relação entre classe e método é feita com o operador :: Este operador também pode acessar os elementos de um namespace. Namespace é como um pacote que carrega variáveis, funções, classes... qualquer coisa. O namespace std é um pacote especial que carrega em seu interior várias ferramentas padrões de C++. É possível também criar seus próprios namespaces e adicioná-los usando a palavra using.

#include <iostream> // Não será adicionado o namespace std. // Veja como são chamados cout e endl. class Ponto { private: int x, y; public: int getx(void); int gety(void); void setx(int x); void sety(int y); ; Ponto(int, int); Ponto(void); ~Ponto(void); int Ponto :: getx(void) { return this->x; int Ponto :: gety(void) { return this->y; void Ponto :: setx(int x) { this->x = x; Ponto :: Ponto(int x, int y) : x(x), y(y) { Ponto :: Ponto(void) { this->x = this->y = 0; Ponto::~Ponto(void) { std::cout << "BUM!" << std::endl; int main(int argc, char **argv) { Ponto *p = new Ponto(7,2); std::cout << p->getx() << std::endl; return 0; Esta sintaxe é feia numa primeira impressão, mas não é difícil e ajuda a visualizar o que uma classe possui. Faça suas classes sempre assim. void Ponto :: sety(int y) { this->y = y;

Métodos Inline C++ possui um modificador que facilita e otimiza o acesso a métodos pequenos: inline. Sempre que um método tiver apenas uma linha (getters e setters, geralmente) ele deve ter a palavra inline antes do tipo de retorno, e este método deve ser criado diretamente na classe, sem o operador ::. Métodos inline são acessados muito mais rapidamente do que os comuns, por isso, sempre que possível, faça-os assim. class Inteiro { private: int valor; public: inline int getvalor(void) { return valor; inline void setvalor(int valor) { this->valor = valor; bool iszero(void); Inteiro(int); ; bool Inteiro :: iszero(void) { if(valor == 0) { return true; else { return false; Inteiro :: Inteiro(int valor) : valor(valor) {