Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 10 Criado por Frederick H. Colclough, Colorado Technical University Ponteiros e Vetores. - ppt carregar
PublicouAntônio Cal Alterado mais de 7 anos atrás
Apresentação em tema: "Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 10 Criado por Frederick H. Colclough, Colorado Technical University Ponteiros e Vetores."— Transcrição da apresentação:
2 Pearson Education Slide 2 Cap í tulo 10 Criado por Frederick H. Colclough, Colorado Technical University Ponteiros e Vetores Dinâmicos
3 Pearson Education Slide 3 Objetivos do Estudo Ponteiros Variáveis ponteiro Gerenciamento de memória Vetores Dinâmicos Criando e usando Aritmética de ponteiros Classes, Ponteiros e Vetores dinâmicos O ponteiro this Destrutores e Construtores de cópia
4 Pearson Education Slide 4 Introdução aos Ponteiros Definição de ponteiro : Endereço de memória para uma variável Lembre-se: A memória é dividida Em posições numeradas Endereços usados como nomes para variáveis Você já usou ponteiros! Argumentos chamados-por-referência O endereço do argumento atual foi passado
5 Pearson Education Slide 5 Variáveis Ponteiro Ponteiros são digitados Pode-se armazenar um ponteiro em uma variável Não int, double, etc. Em vez disso: UM PONTEIRO para int, double, etc! Exemplo: double *p; p é declarado como um ponteiro para a variável double Pode-se armazenar ponteiros para variável de tipo double Não para outros tipos!
6 Pearson Education Slide 6 Declarando Variáveis Ponteiro Ponteiros são declarados assim como outros tipos Adicionar * antes do nome da variável Gera um ponteiro para aquele tipo * deve estar antes de cada variável int *p1, *p2, v1, v2; p1, p2 armazenam ponteiros para variáveis int v1, v2 são variáveis comuns de tipo int
7 Pearson Education Slide 7 Endereços e Números Ponteiro é um endereço Endereço é um inteiro Ponteiro não é um inteiro! Não é loucura é abstração! O C++ insiste em que você utilize um ponteiro como um endereço Mesmo que ele seja um número
8 Pearson Education Slide 8 Apontar Terminologia e visão Fale em apontar, não em endereços Variável ponteiro aponta para a variável comum Torna a visualização mais clara
9 Pearson Education Slide 9 Apontar para … int *p1, *p2, v1, v2; p1 = &v1; Faz a variável ponteiro p1 apontar para a variável int v1 Operador, & Determina o endereço da variável Lê-se: p1 é igual ao enderaço de v1 ou p1 aponta para v1
10 Pearson Education Slide 10 Apontar para … Lembre-se: int *p1, *p2, v1, v2; p1 = &v1; Agora temos dois modos de nos referirmos a v1: A variável v1 propriamente dita: cout << v1; Através do ponteiro p1: cout *p1; Operador de desreferenciação, * Variável ponteiro desreferenciada Significa: Obter dados para os quais p1 aponta
11 Pearson Education Slide 11 Exemplo de Apontar para Considere: v1 = 0; p1 = &v1; *p1 = 42; cout << v1 << endl; cout << *p1 << endl; Gera a seguinte saída: 42 42 p1 e v1 referem-se a mesma variável
12 Pearson Education Slide 12 Operador & O operador de endereço Também usado para especificar parâmetro chamado-por-referência Não é coincidência! Lembre-se: parâmetros chamados-por-referência passam o endereço do argumento atual Os dois usos do operador estão intimamente relacionados
13 Pearson Education Slide 13 Ponteiro: Atribuições Pode-se atribuir o valor de uma variável ponteiro: int *p1, *p2; p2 = p1; Atribui um ponteiro a outro Faz p2 apontar para onde p1 aponta Não vá confundir com: *p1 = *p2; Não se está lidando com os ponteiros p1 e p2, e sim com as variáveis para as quais os ponteiros estão apontando
14 Pearson Education Slide 14 Gráfico de Atribuição de Ponteiros Painel 10.1 página 280
15 Pearson Education Slide 15 O Operador new Como um ponteiro pode se referir a uma variável… Não é preciso ter um identificador padrão Podemos alocar variáveis dinamicamente O operator new cria variáveis Nenhum identificador para referir-se à elas Somente um ponteiro! p1 = new int; Cria uma variável nova sem nome e atribui à p1 que passa a apontar para ela Pode-se acessar com *p1 O uso é exatamente igual às variáveis simples
16 Pearson Education Slide 16 Exemplo de Manipulações Básicas de Ponteiro Painel 10.2 página 281
17 Pearson Education Slide 17 Exemplo de Manipulações Básicas de Ponteiro (cont) Painel 10.2 página 282
18 Pearson Education Slide 18 Manipulações Básicas de Ponteiro: Gráfico Painel 10.3 página 282
19 Pearson Education Slide 19 Mais sobre o Operador new Cria uma variável dinâmica nova Retorna um ponteiro que aponta para a variável Se o tipo for tipo-classe: Construtor-padrão é chamado para o novo objeto Pode-se especificar um construtor diferente incluíndo argumento da seguinte forma: MeuTipo *mtPtr; mtPtr = new MeuTipo(32.0, 17); Pode-se ainda inicializar tipos não-classe: int *n; n = new int(17); // inicializa *n como 17
20 Pearson Education Slide 20 Ponteiros e Funções Ponteiros são tipos completos Podem ser usados exatamente como outros tipos Podem ser parâmetros de funções Podem ser retornados por funções Exemplo: int* encontreOutroPonteiro(int* p); Esta declaração de função: Tem um ponteiro para um parâmetro int Retorna ponteiro para uma variável int
21 Pearson Education Slide 21 Gerenciamento de Memória Pilha Também chamada de freestore Reservada para variáveis dinamicamente alocadas Qualquer variável dinâmica criada consome memória na pilha Se muitas podem consumir toda a memória da pilha Se isso acontecer, qualquer chamada adicional a new falhará.
22 Pearson Education Slide 22 Verificando o Sucesso new Compiladores antigos: Testam se NULL foi retornado pela chamada a new: int *p; p = new int; if (p == NULL) { cout << "Erro: Memória insuficiente.\n"; exit(1); } //Se new foi bem-sucedido, o programa continua a partir daqui.
23 Pearson Education Slide 23 new Bem-sucedida – Compilador Novo Compiladores mais novos: Se a chamada new falhar: O programa termina automaticamente Produzindo uma mensagem de erro Ainda é uma boa prática usar a verificação de NULL
24 Pearson Education Slide 24 Tamanho da Pilha Varia de uma implementação para outra Geralmente é grande A maioria dos programas não utilizarão toda a memória Gerenciamento de Memória Ainda é uma boa prática Princípio sólido de Engenharia de Software A memória é finita independente de quanto se tenha!
25 Pearson Education Slide 25 Operador delete Desaloca memória dinâmica Quando não é mais necessária Devolve a memória para a pilha Exemplo: int *p; p = new int(5); … //processando… delete p; Desaloca memória dinâmica apontada pelo ponteiro p Literalmente destrói a variável dinâmica
26 Pearson Education Slide 26 Ponteiros Oscilantes delete p; Destrói a variável dinâmica mas p ainda aponta para lá! Chamado Ponteiro Oscilante Se p for então desreferenciado ( *p ) Resultados serão imprevisíveis! Freqüentemente desastrosos! Evite os ponteiros oscilantes Fixe-os como NULL antes de desreferenciá-los: delete p; p = NULL;
27 Pearson Education Slide 27 Variáveis Dinâmicas e Automáticas Variáveis Dinâmicas Criadas com o operador new Criadas e destruídas durante a execução do programa Variáveis locais Declaradas dentro de uma definição de função Não-dinâmicas Criadas quando a função é chamada Destruídas quando a chamada de função é completada. Geralmente são chamadas de variáveis automáticas Propriedades controladas por você
28 Pearson Education Slide 28 Definindo Tipos Ponteiro Pode-se definir um nome de tipo ponteiro de modo que as variáveis ponteiros possam ser declaradas como outras variáveis Elimina a necessidade de colocar * na declaração do ponteiro typedef int* IntPtr; Define um novo tipo (alias) Considere estas declarações: IntPtr p; int *p; As duas são eqüivalentes
29 Pearson Education Slide 29 Armadilha: Ponteiros como Parâmetros Chamados por Valor Comportamento imprevisível e problemático Se a função modifica o parâmetro ponteiro modifica apenas na cópia local Melhor ilustrado no exemplo…
30 Pearson Education Slide 30 Exemplo: Ponteiros como Parâmetros Chamados por Valor Painel 10.4 página 287
31 Pearson Education Slide 31 Exemplo: Ponteiros como Parâmetros Chamados por Valor (cont) Painel 10.4 página 288
32 Pearson Education Slide 32 Gráfico de Ponteiros como Parâmetros Chamados por Valor Painel 10.5 página 288
33 Pearson Education Slide 33 Vetores Dinâmicos Variáveis vetores Na verdade são variáveis ponteiros.! Vetor-padrão Tamanho fixo Vetor dinâmico Tamanho não especificado quando se escreve o programa Determinado enquanto o programa é executado
34 Pearson Education Slide 34 Variáveis vetores Lembre-se: vetores são armazenados em endereços de memória, seqüencialmente A variável vetor refere-se à 1 a variável indexada Então a variável vetor é um tipo de variável ponteiro! Exemplo: int a[10]; int * p; a e p são ambas variáveis ponteiro !
35 Pearson Education Slide 35 Variáveis Vetor Ponteiros Lembre-se do exemplo anterior: int a[10]; typedef int* IntPtr; IntPtr p; a e p são variáveis ponteiro Podem atribuir: p = a;// Legal. p agora aponta para onde a aponta Para 1 a variável indexada do vetor a a = p;// ILEGAL!
36 Pearson Education Slide 36 Variáveis Vetor Ponteiros Variável vetor int a[10]; MAIS do que uma variável ponteiro const int * type O vetor já estava alocado na memória A variável a DEVE apontar pará lá…sempre! Não pode ser modificada! Em comparação com ponteiros simples Os quais podem (e tipicamente) o fazem
37 Pearson Education Slide 37 Vetores Dinâmicos Limitações dos Vetores Precisa-se especificar o tamanho Pode não ser conhecido até o programa ser executado! DEVE-SE estimar o tamanho máximo necessário Agumas vezes OK, outras não Gasto de memória Vetores Dinâmicos Podem crescer e encolher conforme a necessidade
38 Pearson Education Slide 38 Criando Vetores Dinâmicos Muito simples! Use o operador new Cria variáveis dinamicamente alocadas Tratadas como vetores Exemplo: typedef double * DoublePtr; DoublePtr d; d = new double[10]; Cria a variável vetor dinamicamente alocada d, com dez elementos, tipo-base double
39 Pearson Education Slide 39 Apagando Vetores Dinâmicos Alocados dinamicamente em tempo de execução Então devem ser apagados em tempo de execução Novamente Simples. Lembre-se do Exemplo: d = new double[10]; … //Processando delete [] d; Desaloca toda a memória para o vetor dinâmico Os colchetes indicam que o vetor existe Lembre-se: d ainda aponta para lá! Deve-se fixar d = NULL;
40 Pearson Education Slide 40 Funções que retornam um vetor Não é permitido que um tipo vetor seja retornado por uma função. Exemplo: int [] umaFuncao( ); //ILEGAL Em vez disso retorne um ponteiro para o tipo-base do vetor: int* umaFuncao( ); //Legal
41 Pearson Education Slide 41 Aritmética de Ponteiros Pode-se efetuar um tipo de aritmética de ponteiros Aritmética de endereços Exemplo: typedef double* DoublePtr; DoublePtr d; d = new double[10]; d contém o endereço de d[0] d + 1 calcula o endereço de d[1] d + 2 calcula o endereço de d[2]
42 Pearson Education Slide 42 Manipulação Alternativa de Vetores Use a aritmética de ponteiros! Atravesse o vetor sem indexar: for (int i = 0; i < tamanhoDoVetor; i++) cout << *(d + i)<< " "; Equivale a: for (int i = 0; i < tamanhoDoVetor; i++) cout << d[i] << " "; Somente adição/subtração com ponteiros Não se pode multiplicar nem dividir Pode-se usar ++ e – com ponteiros
43 Pearson Education Slide 43 Vetores Dinâmicos Multidimensionais Sim, nós podemos! Lembre-se: vetor de vetores Uma Definição de tipo ajuda a vê-los: typedef int* IntVetorPtr; IntVetorPtr *m = new IntVetorPtr[3]; Cria um vetor de 3 ponteiros Cada um dos quais pode nomear um vetor dinâmico de ints for (int i = 0; i < 3; i++) m[i] = new int[4]; O resultado m é um vetor dinâmico de três por quatro.
44 Pearson Education Slide 44 De volta às Classes O operador -> Notação Simplificada Combina o operador de desreferenciação, * e o operador ponto Especifica um membro da classe apontado por um dado ponteiro Exemplo: Registro *p; p = new Registro; p->numero = 2001; p->nota = A;
45 Pearson Education Slide 45 O Ponteiro this Definições de funções membro podem precisar se referir ao objeto que faz a chamada Use o ponteiro predefinido this Automaticamente aponta para o objeto que faz a chamada: class Amostra { public:... void mostraAlgo( ) const;... private: int algo;... }; Duas formas para a função membro: cout << algo; cout algo;
46 Pearson Education Slide 46 Sobrecarregando o Operador de Atribuição O operador de atribuição retorna uma referência Assim, atribuíções encadeadas são possíveis ex.: a = b = c; Fixa a e b igual a c Operador deve retornar algo de mesmo tipo que seu lado esquerdo Para garantir que o encadeamento funcione O ponteiro this ajudará com isso!
47 Pearson Education Slide 47 Sobrecarregando o Operador de Atribuição Lembre-se: O operador de atribuição deve ser membro da classe Tem um parâmetro O operando esquerdo é o objeto que chama s1 = s2; Pense como: s1.=(s2); s1 = s2 = s3; Requer (s1 = s2) = s3; Então (s1 = s2) deve retornar um objeto do tipo s1 E passar para = s3;
48 Pearson Education Slide 48 Definição do Operador = Sobrecarregado Exemplo de uso da classe string:
49 Pearson Education Slide 49 Cópia Rasa e Cópia Profunda Cópia Rasa Operador de atribuição copia o conteúdo de variáveis-membros de um objeto a outro Operador de atribuição padrão e o construtor de cópia padrão executam cópias rasas. Cópia Profunda Ponteiros e Memória dinâmica envolvidos Deve-se desreferenciar variáveis ponteiro para conseguir dados para a cópia Escreva seu próprio operador de atribuição sobrecarregado o construtor de cópia nesse caso!
50 Pearson Education Slide 50 Destrutores Variáveis dinâmicamente alocadas Não vão embora até que delete seja chamada Se os ponteiros são somente membors privados Eles dinâmicamente alocam dados reais No construtor Deve-se ter meios para desalocar quando o objeto for destruído Resposta: destrutor!
51 Pearson Education Slide 51 Destrutores Oposto a construtor Automaticamente chamado quando um objeto da classe sai do escopo. Versão padrão somente remove variáveis simples, e não dinâmicas Definido como o construtor, somente adicione ~ MinhaClasse::~MinhaClasse() { //Responsável pela limpeza }
52 Pearson Education Slide 52 Construtores de Cópia Automaticamente chamados: 1. Quando um objeto classe é declarado e inicializado por outro objeto 2. Quando a função retorna um valor do tipo classe 3. Quando um objeto classe é declarado e inicializado por outro objeto Requer uma cópia temporária do objeto O construtor de cópia a cria Construtor de cópia padrão Como padrão só copia o conteúdo de variáveis membro
53 Pearson Education Slide 53 Sumário 1 Ponteiro é um endereço de memória Fornece referência indireta à variável Variáveis dinâmicas Criadas e destruídas enquanto o programa é executado Pilhas Armazenamento na memória de variáveis dinâmicas Vetores alocados dinâmicamente Tamanho determinado enquanto o programa roda
54 Pearson Education Slide 54 Sumário 2 Destrutor de classe Função membro especial Destrói objetos automaticamente Construtor de cópia Função-membro de argumento simples Chamado automaticamente quando uma cópia temporária é necessária Operador de Atribuição Deve ser sobrecarregado como uma função-membro Retorna referência para encadeamento
Carregar ppt "Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 10 Criado por Frederick H. Colclough, Colorado Technical University Ponteiros e Vetores."