Contents

Programação Orientada a Objetos - POO04


Programação Orientada a Objetos em C++ - POO04

Sobrecarga de funções construtoras


As funções construtoras, embora sejam executadas uma única vez, quando da criação do objeto, de resto são idênticas as demais funções do C. Assim podem receber parâmetros na sua chamada. Quando o objeto é criado, nesta hora passamos o parâmetro para a função construtora, colocando o parâmetro entre parênteses após o nome do objeto, na declaração do mesmo. O conceito de overload de função também é valido para funções construct e assim podemos ter para um único objeto diversas funções construct, todas com o mesmo nome e com parâmetros de tipos diferentes. Será executada aquela função que tem correspondência com os tipos de parâmetros passados. O exemplo que segue mostra este uso.

clas20.cpp no FTP ou veja aqui...
clas20.cpp

Variáveis Locais em C++


No C as variáveis são todas declaradas no início da função. No C++ podemos declarar variáveis em qualquer lugar do programa. Esta forma pode ficar mais interessante quando se quer encapsular os dados juntos com um rotina de procedimentos. O exemplo que segue mostra o uso de variáveis locais.

clas21.cpp no FTP ou veja aqui...
clas21.cpp

Inicialização dinâmica


Em C++ tanto as variáveis locais quanto globais, podem ser inicializadas em tempo de execução. Isto é chamado de inicialização dinâmica. Em C uma variável deve ser inicializada usando-se uma expressão constante. Por exemplo estas inicializações são válidas:

	int n = atoi (gets(str));
	long pos = ftell (fp);
	double d = 1.02 * count / deltax;

Assim o exemplo do programa anterior pode ser aperfeiçoado como mostrado a seguir.

clas22.cpp no FTP ou veja aqui...
clas22.cpp

Aplicando Inicialização dinâmica aos Construtores


Assim como as variáveis simples os objetos podem ser inicializados dinamicamente quando são criados. Essa característica permite criar o tipo exato de objeto, usando-se a informação sobre os dados, conhecidas somente em tempo de execução. Como exemplo temos o programa já visto anteriormente, refeito com inicialização dinâmica de variáveis.

clas23.cpp no FTP ou veja aqui...
clas23.cpp


A palavra reservada THIS


Cada vez que se invoca uma função membro, automaticamente é passado um ponteiro para o objeto que a invoca. Podemos acessar este ponteiro usando a palavra this. O ponteiro this é um parâmetro implícito para todas as funções membros. Por exemplo, dado a class

	class c1  {
	  int i;
	  ....
	 };
uma função membro pode atribuir a i o valor 10 usando:
	i = 10;
esta declaração é uma abreviação para:
	this ->i=10;
Para ver como o ponteiro this funciona vejamos este pequeno programa:
	#include <iostream.h>
	clas cl {
	  int i;
	public:
	  void carrega_i(int val) { this->i = val;} // o mesmo que i=val
	  int obtem_i(void)  {return this-> i;} // o mesmo que return i
	};
	void main(void)
	{
	  cl o;
	  o.carrega_i(100);
	  cout << o.obtem_i();
	}


Sobrecarga de Operador


Outra característica do C++ relacionada a sobrecarga de funções é a sobrecarga de operadores. Muitos operadores do C++ podem receber significados especiais relativos a classes específicas. Por exemplo uma class que define uma lista ligada pode usar o operador + para adicionar um objeto a lista. Outra class pode usar o operador + de uma maneira inteiramente diferente. Quando um operador é sobrecarregado, nada do seu significado original é perdido. Para sobrecarregar um operador devemos definir o que a dada operação significa em relação a class em que ela é aplicada. Para isso criamos uma funçaã operator que define a sua ação. A forma geral da função operator é a seguinte:

	tipo nome_da_class::operator#(lista de argumentos)
	{
	     //operaçào definida relativa à classe
	}
Aqui o tipo é o tipo do valor retornado pela operação específica. Um operador sobrecarregado tem freqüentemente um valor de retorno do mesmo tipo da class para onde é sobrecarregado. Funções operator devem ser membros ou friend da class na qual estão sendo usadas. Existe alguma diferença entre sobrecarregar uma função membro e uma função friend. Por enquanto veremos um exemplo com funções membro. No exemplo que segue uma class chamada tres_d que mantém as coordenadas de um objeto no espaço, com sobrecarga nos operadores + e =.

clas24.cpp no FTP ou veja aqui...
clas24.cpp

Quando examinamos o exemplo anterior vemos que as funções operator tem somente um parâmetro, embora sobrecarreguem operações binárias. A razão é que só precisamos do segundo argumento da operação binária pois o primeiro está implícito usando o ponteiro this . Assim na linha
		temp.x = x + t.x;
o x refere-se a this->x que é o x associado ao objeto que solicitou a chamada da função. Quando o operador + é sobrecarregado ele retorna um objeto do tipo tres_d.
Assim dois objetos são somados, retornando um terceiro objeto. Já o operador de atribuição faz com que o argumento seja modificado No caso de atribuição a operação é realizada no objeto que gera a chamada para a função pela passagem implícita do ponteiro this. Assim o conteúdo do objeto alterado retorna com *this;
Posteriormente veremos que é possível sobrecarregar operadores unários como ++ ou --. A operação é realizada no objeto que gera a chamada, pela passagem implícita do ponteiro this. Veja uma versão expandida do programa anterior agora com implementação dos operadores unário ++.

clas25.cpp no FTP ou veja aqui...
clas25.cpp

Um ponto importante é que não podemos determinar se o operador precede ou segue o seu operando. Assim
	++OBJ;
ou
	OBJ++;  (desta forma o Turbo C dá warning)
funcionam da mesma forma e a função operator funciona igual nas duas formas de chamada. Outro ponto importante é que na sobrecarga de operadores normalmente se usa o operador para que ele produza o mesmo resultado como se fosse em sua função original, apenas aplicado a objetos. Os únicos operadores que não podem ser sobrecarregados são:
	.  ::   .*   ?

Função Operator com Atributo Friend


É possível para uma função operator ser uma friend de uma class em vez de membro. Neste caso não tem o argumento implícito this. Desta forma quando friend é usada dois operandos são passados explicitamente para um operador que sobrecarregue operadores binários e um único operando é passado quando se sobrecarrega operadores unários. Os únicos operadores que não podem usar as funções friend são =, ( ), [], e ->. Como exemplo temos uma versão do programa anterior que usa função friend em vez de função membro para sobrecarregar a função +.

clas26.cpp no FTP ou veja aqui...
clas26.cpp

Como podemos ver, os dois operandos são passados para a função operator+(). O operando da esquerda é passado em op1 e o da direita em op2. Normalmente não é necessário usar a função friend em vez de função membro. Entretanto tem uma situação que é necessário usar função friend. No caso dos operadores binários o objeto da esquerda invoca a função. Isso é apropriado contanto que o objeto da esquerda defina a operação específica. Assim se temos o objeto OBJ,

	OBJ = OBJ + 10;  //  funciona normal
mas
	OBJ = 10 + OBJ;   // Não funciona

pois o objeto da esquerda é um inteiro um tipo interno para o qual nenhuma operação envolvendo um inteiro e um objeto do tipo OBJ é definida. Para solucionar este caso podemos definir duas funções friend, conforme exemplo que segue:

clas27.cpp no FTP ou veja aqui...
clas27.cpp

Referência


Por definição o C e o C++ passam argumentos para uma função usando chamada por valor. Assim é passado uma cópia do dado argumento e o original fica inalterado. Em C (e opcionalmente em C++) quando uma função precisa alterar os valores das variáveis recebidas como argumentos, os parâmetros precisam ser explicitamente declarados como tipo ponteiros e a função deve operar nas variáveis chamadas usando o operador de ponteiro *.
Em C++ é possível dizer ao compilador para gerar automaticamente uma chamada por referencia, em vez de uma chamada por valor. Isto é feito precedendo o nome do parâmetro na declaração da função pelo operador &.

Exemplo:
	void func1(float &f)
	{
	  f = rand();  // modifica o argumento de chamada 
	}
idêntico ao C
	void func(float *p)
	{
	  *p=rand();
	}

Outro Exemplo de Sobrecarga de Operador


Este exemplo implementa um tipo string e define varias operações relativas a ele. Usa uma clas string e diversas operações sobre ela.

class28 no FTP ou veja aqui...
clas28.cpp


Contents