Princípios de programação em Linguagem C++ - PDF
Download "Princípios de programação em Linguagem C++"
Sarah Chagas Pinhal
1 Universidade Federal de Santa Maria Departamento de Eletrônica e Computação Prof. Cesar Tadeu Pozzer Princípios de programação em Linguagem C++ 1 Introdução A Linguagem C++ é uma extensão da linguagem C que incorpora recursos de Orientação a Objetos. Todas as características da linguagem C estão disponíveis na linguagem C++. Neste curso será feita uma abordagem introdutória a esta linguagem mostrando os principais recursos e características. 2 Sobrecarga de Operadores Da mesma forma como métodos, pode-se também fazer a sobrecarga de operadores, o que permite a realização de operações sobre tipos de dados não básicos sem a necessidade de chamadas de funções específicas. A seguinte tabela ilustra a lista de todos os operadores que podem ser sobrecarregados. + - * / = < > += -= *= /= << >> <<= >>= ==!= <= >= % & ^! ~ &= ^= = && %= [] () new delete A definição de sobrecarga é feita pela definição de métodos de uma classe cujo nome é operator seguido pelo operador que se deseja sobrecarregar. O seguinte exemplo ilustra a definição da classe Vector3, para manipulação de vetores. class Vector3 public: float x, y, z; Vector3(float vx, float vy, float vz) x = vx; y = vy; z = vz;
2 Vector3(const Vector3& u) x = u.x; y = u.y; z = u.z; void operator+= (const Vector3& v) x += v.x; y += v.y; z += v.z; //produto vetorial entre dois vetores Vector3 operator ^ (Vector3& v) Vector3 aux( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); return( aux ); Vector3 operator + (const Vector3& v) Vector3 aux( x + v.x, y + v.y, z + v.z ); return( aux ); ; void imprime( ) const printf("%f %f %f", x, y, z); Neste exemplo pode-se observar o surgimento de dois operadores: const e &. O operador const é usado para assegurar que o parâmetro passado para a função não poderá ser alterado. O operador & indica que o parâmetro será passado por referência, porém todas as operações sobre ele e em sua chamada são como se fosse uma variável passada por valor. O operador const ao lado da declaração da função indica que a função não poderá alterar nenhum membro da classe. Com a definição destes operadores, pode-se facilmente somar, incrementar e calcular o produto vetorial de dois vetores, como no seguinte exemplo. Vector3 v1(1,1,1), v2(2,2,2), v3(1,1,1);
3 v1+=v2; v1.imprime(); v3 = v1^v2; v3.imprime(); 3 Métodos Inline Funções inline são comuns em C++, tanto em funções globais como em métodos de classes. Estas funções têm como objetivo tornar o código mais eficiente. Elas são tratadas pelo compilador quase como uma macro: a chamada da função é substituída pelo corpo da função. Para funções pequenas, isto é extremamente eficiente, já que evita geração de código para a chamada e o retorno da função. Este tipo de otimização normalmente só é utilizado em funções pequenas, pois funções inline grandes podem aumentar muito o tamanho do código gerado. Do ponto de vista de quem chama a função, não faz nenhuma diferença se a função é inline ou não. Nem todas as funções declaradas inline são expandidas como tal. Se o compilador julgar que a função é muito grande ou complexa, ela é tratada como uma função normal. No caso de o programador especificar uma função como inline e o compilador decidir que ela será uma função normal, será sinalizada uma warning. O critério de quando expandir ou não funções inline não é definido pela linguagem C++, e pode variar de compilador para compilador. Para a declaração de funções inline foi criada mais uma palavra reservada, inline. Esta deve preceder a declaração de uma função inline: inline double quadrado(double x) return x * x; Alguns detalhes devem ser levados em consideração durante a utilização de funções inline. O que o compilador faz quando se depara com uma chamada de função inline? O corpo da função deve ser expandido no lugar da chamada. Isto significa que o corpo da função deve estar disponível para o compilador antes da chamada. Um módulo C++ é composto por dois arquivos, o arquivo com as declarações exportadas (.h) e outro com as implementações (.c ou.cpp). Tipicamente, uma função exportada por um módulo tem o seu protótipo no.h e sua implementação no.c. Isso porque um módulo não precisa conhecer a implementação de uma função para usá-la. Mas isso só é verdade para funções não inline. Por causa disso, funções inline exportadas precisam ser implementadas no.h e não mais no.c.
4 4 Template A sobrecarga de funções permite a declaração de métodos com mesmo nome e diferentes tipos de parâmetros. Porém, para cada tipo de parâmetro, um novo método deve ser definido. Uma solução para este problema é o uso de Templates, que permitem criar funções genéricas que admitem qualquer tipo de parâmetro para argumentos e retorno. O seguinte exemplo ilustra a sintaxe para definição de uma função template que retorna o maior valor entre dois números de mesmo tipo. template <class GenericType> GenericType getmax (GenericType a, GenericType b) return (a>b?a:b); A função getmax pode ser chamada com qualquer tipo de parâmetro, que será substituído por GenericType em tempo de execução. No seguinte exemplo a função getmax é chamada com parâmetros inteiros e long. template <class T> T GetMax (T a, T b) T result; result = (a>b)? a : b; return (result); int main () int i=5, j=6, k; long l=10, m=5, n; k=getmax<int>(i, j); n=getmax<long>(l, m); k=getmax (i, j); n=getmax (l, m); A definição do tipo de parâmetro <int>, <long> é opcional pois o compilador detecta automaticamente o tipo e o converte. Caso os parâmetros forem de tipos diferentes, devese definir o Template com dois tipos genéricos
5 template <class T, class U> T GetMin (T a, U b) return (a<b?a:b); Templates também podem ser definidos para comportar classes, que podem conter métodos com parâmetros genéricos, como no seguinte exemplo: template <class T> class par T valores[2]; public: par(t first, T second) valores[0]=first; valores[1]=second; ; A definição de um objeto do tipo par chamado Ponto, para armazenar dois valores inteiros tem a seguinte sintaxe: pair<int> Ponto (115, 36); 5 STL - Standard Template Library STL é um conjunto de tipos abstratos de dados e funções projetados para manipularem diferentes tipos de dados de forma transparente. As operações sobre os dados são realizadas por métodos que também aceitam tipos de dados genéricos. Como o próprio nome diz, STL faz uso de templates, ja definidos, para implementação de diversos algoritmos que manipulam dados de forma eficiente, como por exemplo vetores, dinâmicos, listas, pilhas, etc. No STL também foi adicionado um tipo String, que facilita as operações de manipulação de caracteres quando comparado a biblioteca string.h da linguagem C. Além dissso, também existem funções de busca, ordenação, dentre outros. Nesta seção serão abordadas 3 estruturas sequenciais: vetor, fila dupla (Deque) e lista. A escolha de uso é dada em função das operações que se deseja realizar sobre dos dados. A seguinte tabela mostra o tempo gasto para diferentes operações sobre cada um dos tipos de representação.
6 Tabela 1: Tempo de execução de diferentes operações Operação Vector Deque Lista Acessar o primeiro elemento Constante Constante Constante Access último elemento Constante Constante Constante Accessar elementos randômicos Constante Constante Linear Add/Delete no início Linear Constante Constante Add/Delete no final Constante Constante Constante Add/Delete randomicamente Linear Linear Constante Ao se usar STL, deve-se ter em mente o conceito de namespace, que permite agrupar classes, objetos e funções e associa-los a um nome, o que facilita a quebra de escopos globais em subescopos menores. namespace teste int a, b; Para acessar as variaveis a e b, deve-se indicar o escopo associado usando-se o operador ::, como no seguinte exemplo: teste::a = 10; Em STL, todas as classes, objetos e funções são definidos com o namespace std. Pode-se usar o operador de escopo a cada uso da STL ou indicar o namespace corrente, da seguinte forma: using namespace std; Para fazer o percorrimento de todos os elementos da estrutura são usados Iterators. Eles podem ser vistos como ponteiros para posições específicias da estrutura. Nas seções subsequentes serão apresentados vários exemplos do uso de namespace e iterators para 3 tipos de containers STL.
7 5.1 Vector O tipo vector é similar a um array, com a diferença que possui tamanho dinânico. As principais funções defindas são: begin() Retorna um iterator para o iníco do vetor end() Retorna um iterator para o final do vetor push_back( ) Adiciona elemento no final do vetor pop_back( ) Destroi elemento no final do vetor size() Número de elemtos do vetor [] Operador de acesso randômico #include <stdio.h> #include <vector> //using namespace std ; void main(void) int val; std::vector<int> v; std::vector<int>::iterator iter; printf("digite alguns valores inteiros: "); do scanf("%d", &val); v.push_back(val); while(val!=-1); for( iter=v.begin(); iter!= v.end(); iter++ ) printf("%d ", *iter); //acesso com o operador randomico for( int i=0; i<v.size(); i++) printf("%d ", v[i] );
8 5.2 Deque Uma Deque é muito similar a um vetor, com a característica de apresentar rápida inserção e remoção de elementos no início e no final. Possui funções de acesso iguais ao Vector, e duas adicionais: push_front( ) pop_front( ) Adiciona elemento no início da Deque Destroi elemento no início da Deque Para usar este template, deve-se adicionar a diretiva #include <deque>. 5.3 List O tipo List, como mostrado na Tabela 1, deve ser usado preferencialmente quando existem muitas inserções e remoções de dados em posições intermediárias. Em todas as demais operacões, por não possuir o operador [], tem um alto custo computacional. O tipo List faz uso de uma implementação com listas duplamente encadeadas, o que necessita grande consumo de memória. Os principais métodos são semelhantes ao Deque. // ANSI C Headers #include <stdlib.h> // C++ STL Headers #include <list> #ifdef _WIN32 using namespace std; #endif class Vector3 float x, y, z; public: Vector3()
9 ; Vector3(const float mx, const float my, const float mz) x = mx; y = my; z = mz; void imprime() printf("\n\ndados do ponto: "); printf("x=%f, y=%f, z=%f", x, y, z); int main( void ) int i; list< Vector3> list; //o std:: não eh necessario quando se usa namespace std::list< Vector3>::iterator iter; for(i=0; i<3; i++) list.push_front( Vector3(i, i, i) ); for(iter = list.begin(); iter!=list.end(); iter++) Vector3& v1 = *iter; //por referencia v1.imprime(); // ou Vector3* v2 = &( *iter ); //por referencia v2->imprime(); //ou Vector3 v3 = *iter;//por copia v3.imprime(); //insere um elemento em uma posicao intermediaria iter = list.begin(); iter++; Vector3 v = (Vector3)*iter;
10 list.insert( iter, Vector3(20,20,20) ); for(iter = list.begin(); iter!=list.end(); iter++) Vector3& v = *iter; v.imprime(); return( 0 ); 6 Referências Bibliográficas [1] Soulié, J. CPP Tutorial. Disponível em: [2] Ottewell, P. STL Tutorial. Disponível em: [3] Borges, R., Clinio, A. L. Programação Orientada a Objetos com C++. Tutorial
Templates. Introdução. Motivação. Thiago Rosso Adams
Templates Thiago Rosso Adams http://www.thradams.com thiago.adams@gmail.com Introdução Apesar de toda biblioteca padrão usar templates, muitas pessoas ainda têm uma visão muito superficial sobre este assunto,
Vectores em C++ Classe vector: Introdução
Vectores em C++ FEUP - MIEEC Programação 2-2008/2009 Classe vector: Introdução A classe vector é uma alternativa à representação de array primitivo Template de classe necessário especificar o tipo dos
Roteiro de estudos para maratona de. Autores: André Luís Tibola Guilherme Fickel
Roteiro de estudos para maratona de programação Autores: André Luís Tibola Guilherme Fickel Versão 0.3 17 de maio de 2010 2 Sumário 1 Introdução 5 1.1 Estrutura do livro................................
Linguagem de Programação I Carlos Eduardo Batista Centro de Informática - UFPB bidu@ci.ufpb.br Exemplo: Explorar Templates e Exceções Incrementar com o uso de STL 2 STL é uma biblioteca padrão com as estruturas