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
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
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 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
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(); }
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 =.
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.
++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:
. :: .* ?
É 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
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(); }
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