Você está na página 1de 3

Professora Isabel Harb Manssour

Linguagem de Programao C++ 25



7. PASSAGEM DE PARMETROS

interessante ressaltar que a criao de novas classes de objetos uma atividade primria da
programao orientada a objetos, e a complexidade do programa geralmente escondida nestes objetos. Sendo
assim, escrever a funo main() consiste em gerenciar objetos. Um tpico mais complexo sobre criar um tipo
definido pelo usurio (ou classe de objetos) a passagem de objetos para, e retorno de objetos de funes.
Nesta seo descrita a passagem de parmetros, sendo que dada especial ateno construo de classes
complexas que podem ser passadas e retornadas corretamente.

Uma funo comunica-se com o "mundo externo" de duas maneiras: mudando os valores que so
globais funo ou atravs de passagem e retorno de valores. A informao pode ser movida da/para funo de
duas maneiras:
Uma cpia da varivel inteira feita;
Somente o endereo da varivel transferido pelos limites.

O primeiro mtodo chamado passagem por valor. J que feita uma cpia do argumento (ou
varivel), esta pode ser usada e alterada dentro da funo sem afetar a varivel da qual ela foi gerada.
Entretanto, quando uma funo precisa ser capaz de alterar os valores das variveis usadas como argumentos,
os parmetros precisam ser explicitamente declarados como tipos ponteiros. Assim, utiliza-se o segundo mtodo
que chamado de passagem por nome, quando um ponteiro passado, ou de passagem por referncia,
quando referncias so usadas. Em ambos os casos um endereo manipulado.

Os endereos so passados por duas razes. A primeira simplesmente pela eficincia; sabendo-se que
a varivel ser somente lida, ento, geralmente mais rpido passar o endereo quando se usam objetos
maiores do que um ponteiro. Existe tambm um benefcio adicional em se passar um endereo. No caso de
objetos, passa-se o endereo para um objeto inicializado e o tamanho do endereo sempre o mesmo, assim
no h problema envolvendo cpia e inicializao.

A segunda razo para passar um endereo manipular fisicamente o objeto ou varivel para o qual o
endereo aponta, isto , pode-se alterar uma varivel ou objeto que externo a uma funo. Normalmente, os
resultados de uma chamada de funo devem ser expressos pelo valor de retorno da funo, mas existem
situaes em que isso no satisfatrio. Por exemplo, a funo pode precisar alterar mais de um objeto. Se os
endereos do objeto so passados, a funo pode afetar diretamente qualquer nmero de objetos na funo
chamadora.

Na passagem por nome, so explicitamente declarados ponteiros e passados endereos. J passar por
referncia o mesmo que declarar um argumento para ser um ponteiro e, ento, passar um endereo. Com
referncias, entretanto, o compilador faz todo o trabalho para o usurio: ele fora o endereo a ser passado
dentro de uma funo, ainda que o usurio no pegue o endereo explicitamente. Dentro da funo, pode-se
manipular os itens como se fossem objetos. Isso um grande avano, uma vez que muitos erros quando se
usam bibliotecas da linguagem C, podem ser atribudos confuso sobre como passar um endereo. Como o
compilador da linguagem C++ manipula os detalhes, quando se passa argumentos por referncia, muito poucos
erros ocorrem. Tambm muito mais eficiente passar um ponteiro do que copiar o objeto inteiro dentro da
funo chamada.

Entretanto, existem casos onde preciso uma cpia de um objeto a ser criado dentro da janela da
funo. Pode-se necessitar modificar o objeto sem querer que o original seja tocado. Nesses casos, deve-se
passar o objeto por valor. Se o compilador passa um int ou float, por exemplo, ele sabe o que fazer: uma cpia
Professora Isabel Harb Manssour
Linguagem de Programao C++ 26

do dado empurrada na pilha antes que a funo seja chamada. Quando se passa um tipo definido pelo usurio,
entretanto, o compilador no tem idia de como manipul-lo.

No caso de uma classe "simples" (nenhum dos dados-membros so ponteiros) onde no foi definido um
inicializador de cpia, o compilador recorre a uma cpia bit a bit, que copia todos os bytes da struct do objeto
antigo na struct do novo objeto. Porm, se alguns dos membros da classe so ponteiros, uma "cpia mais
complexa" usualmente requerida para alocar memria livre e copiar os itens que so apontados [1].

O exemplo abaixo ilustra a passagem por valor e por referncia:

void f (int val, int& ref)
{
val ++;
ref++;
}

void g ()
{
int i = 1,
j = 1;
f(i, j);
}

Neste caso, quando "f()" chamada, "val++" incrementa uma cpia local do primeiro argumento, enquanto
"ref++" incrementa o segundo argumento. Sendo assim, na funo "g()", "j" incrementado, mas "i" no, pois o
primeiro passado por referncia e o segundo por valor.

Se um vetor usado como argumento, um ponteiro para o seu elemento inicial passado. Por exemplo:
:
int strlen(const char*);
void f()
{
char v[] = "an array";
int i = strlen(v);
int j = strlen("Nicholas");
}
:
Vetores diferem de outros tipos nos quais um vetor no (e no pode ser) passado por valor. O tamanho do
vetor no disponvel para a funo chamada [8].

Torna-se importante salientar que se uma expresso especificada em uma declarao de argumentos,
essa expresso usada como um argumento default. Todos os argumentos subseqentes devem ter
argumentos default fornecidos nessa ou em declaraes prvias desta funo. Um argumento default no pode
ser redefinido por uma declarao posterior (ainda que para o mesmo valor). Porm, uma declarao pode
acrescentar argumentos default no fornecidos em declaraes anteriores.

Na declarao:
ponto (int = 3, int = 4);
tem-se uma funo que pode ser chamada com zero, um ou dois argumentos do tipo int. Ela pode ser chamada
de qualquer dessas formas:
ponto (1, 2); ponto (1); ponto ();
As duas ltimas chamadas so equivalentes a "ponto(1,4)" e "ponto(3,4)", respectivamente [2].

Ponteiros tambm podem ser argumentos de funes, apesar disto no ser muito usual em C++, uma
vez que existem os parmetros de referncia. Assim sendo, para passar um argumento para uma funo para
uso direto, uma instruo deve passar um "endereo" desse argumento para um parmetro do tipo ponteiro.

Professora Isabel Harb Manssour
Linguagem de Programao C++ 27

A seguir ser apresentado um exemplo que mostra a diferena entre usar os parmetros por referncia e
passar um ponteiro como argumento. Supondo que foi criada a seguinte estrutura para acompanhar as
temperaturas baixas e altas:
struct temp
{
float alta;
float baixa;
}
Esta estrutura usada em um programa que faz o acompanhamento das leituras altas e baixas de um
termmetro de algum modo ligado ao computador. Uma funo-chave neste programa l a temperatura corrente
e modifica o campo apropriado em uma estrutura do tipo "temp" passada por referncia para uma funo. O
cdigo fica da seguinte maneira:

:
temp atemp;
resgistratemp(atemp);
:
void registratemp (temp &t)
{
float atual;

pegatempatual(atual);

if (atual > t.alta)
t.alta = atual;
else if (atual < t.baixa)
t.baixa = atual;
}
:

Neste exemplo, como o parmetro de "registratemp" passado por referncia, a funo opera
diretamente na varivel "atemp". Se o parmetro no tivesse sido declarado com &, a funo operaria apenas
sobre uma cpia do valor desse argumento. Com exceo do caracter &, entretanto, as instrues da funo so
idnticas, tenha sido o parmetro passado por valor ou por referncia.

No cdigo abaixo, as instrues da funo consideram que "t" um ponteiro e no uma varivel:
:
resgistratemp(&atemp);
:
void registratemp (temp *t)
{
float atual;

pegatempatual(&atual);

if (atual > t->alta)
t->alta = atual;
else if (atual < t->baixa)
t->baixa = atual;
}
:
Neste caso, em vez de usar expresses como "t.alta" e "t.baixa" para fazer referncias aos campos da estrutura,
as instrues devem usar o smbolo "->" [4].

importante salientar que quando um objeto passado como um argumento para uma funo, uma
cpia desse objeto feita. Alm disso, quando a cpia feita, a funo construtora desse objeto no chamada.
No entanto, quando a funo termina, a destrutora da cpia chamada. Se, por alguma razo, o usurio no
desejar fazer uma cpia ou no quiser que a funo destrutora seja chamada, basta passar o objeto por
referncia. Quando um objeto passado por referncia, nenhuma cpia dele feita. Isso significa que nenhum
objeto usado como parmetro e destrudo quando a funo termina, e a destrutora do parmetro no chamada.

Você também pode gostar