• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

shumy

[C] - [1] Ponteiros vs referências.

8 mensagens neste tópico

Este tópico vai ser um dos primeiros, entre outros que pretendo adicionar, que tem objectivo de abrir a mente para assuntos menos discutidos sobre a linguagem C++.

Os assuntos serão variados e não terão em principio qualquer relação entre eles, não obstante espero que sejam interessantes e que vos façam pensar.

Então…

Diferenças entre ponteiros e referencias para além das evidentes e que já são mencionadas quando nos é ensinado os pormenores da linguagem, deixo o link para saberem a que me refiro: http://en.wikipedia.org/wiki/Reference_(C%2B%2B)

Existe uma diferença meramente semântica e que não é tratada pelo compilador, fica ao cargo do programador a boa aplicação desta regra, no entanto tomando conhecimento dela ajuda bastante a escolher entre o uso de ponteiros ou referências.

Podemos dizer que um ponteiro traz uma responsabilidade associada, a responsabilidade de gerir a memória para a qual aponta. Uma função que retorna um ponteiro retorna também a responsabilidade de gestão de memória, pelo menos esta devia ser a regra, o que nem sempre é assim.

Apresento um exemplo de uma classe simplificada:

class Xpto
{
private:
ObjectX* x;
public:
//...

ObjectX* CreateX(){new ObjectX;}
ObjectX& MyX(){return *x;}
};

Temos a função CreateX() que retorna um ponteiro para ObjectX e como tal deve ser interpretado como retornando também a responsabilidade de gerir a memória. Teremos de libertar a memória criada na função CreateX() e a classe descarta qualquer responsabilidade sobre esse assunto, a responsabilidade fica a cargo de quem chamou a função. De notar que o nome da função também é explícito nesse aspecto, mas mesmo que não o fosse o facto de retornar um ponteiro tomamos como regra geral que a responsabilidade fica desassociada da função.

A função MyX() retorna uma referência e embora seja também do tipo ObjectX, quem fez a chamada a função não deve sequer tentar efectuar um delete sobre o retorno de MyX(). A classe é o “owner” da memória. Nunca se deve tentar libertar memória de uma referência, embora o compilador não se prenuncie, o desastre pode acontecer em “runtime”.

Retornando o tipo incorrecto nas funções anteriores pode levar ao engano do programador, libertando memória que não deveria, criando ponteiros inválidos dentro da classe ou inversamente criando “memory leaks”.

Alguns programadores referem que retornam sempre ponteiros porque preferem trabalhar com ponteiros, sendo estes com maior potencial em relação a referências.

Uma coisa não impede a outra e é péssima prática porque pode muito bem guardar uma referência em um ponteiro se tal for necessário:

Xpto* x = new Xpto();
ObjectX& ox1 = x->MyX(); //guardar em ref
ObjectX* ox2= &x->MyX();  //guardar em pointer

Para uma boa regra nada como uma boa excepção. Os arrays de caracteres, típicos char* são causa de alguns problemas se não forem correctamente compreendidos.

char* str1 = "string\0";

A “string\0” é colocada no ponteiro no entanto não será necessário libertar memória, isto parece um contra-senso, mas afinal “string\0” também não é nenhuma função, é uma excepção funcional introduzida no próprio compilador. Uma forma de simplificar o uso de conjuntos de caracteres.

Em conclusão, a regra aplica-se essencialmente no retorno de funções e diferencia de uma forma mais exacta o uso de referências vs ponteiros no retorno de funções. Para a próxima já não terá tantas duvidas se deve usar um ponteiro ou uma referência.

Artigo no wiki em: http://wiki.portugal-a-programar.pt/dev_geral:cpp:ponteiros_vs_referencias

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

so uma questa quando fazes

ObjectX& MyX(){ return *x; }

quando fazes o return *x; nao estas a desreferenciar o objecto apontado por x ?

boas programacoes

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

x é ponteiro logo tens de desreferenciar para retornar o objecto, objecto este que é retornado por referência e não por cópia.

O mesmo acontece quando se retorna uma referência do ponteiro "this".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

humm e que eu estava a pensar se nao se podia ter retornado logo x

ou seja

ObjectX& MyX(){
return x;
}

uma vez que o que a funcao retorna e um endereco

podias dar mais uns exemplos e que ainda assim fiquei um bocado baralhado

obg e boas programacoes

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

uma vez que o que a funcao retorna e um endereco

Não é um endereço, é uma referência. O símbolo & tem significados diferentes conforme o sítio onde é usado.

Quando é numa declaração, seja de uma variável, seja de uma função, significa "referência para objecto do tipo".

int c = 0;

int &x = c;

int &umareferencia(int &x);

Em todos os exemplos acima, & significa "referência para uma variável do tipo int".

Se for antes de uma variável ou função, sem ser na declaração das mesmas, é um operador unário, e significa "o endereço de":

int func(int i) { return i+1; }

int (*ptr_para_func)(int);

ptr_para_func = &func;

Neste exemplo, & significa "endereço da função 'func'".

int i = 10;

int *pi = &i;

E neste, & significa "endereço da variável i".

Se for entre duas variáveis, é um operador binário e significa "and bit a bit":

int a = b & c;

Mas isto não interessa para o caso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

The dark, a referencia de uma variavel (objecto) nao é o endereco de memoria onde esta esta guardada?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

No fundo, é. Uma referência é um apontador "disfarçado", açúcar sintáctico do C++, que se comporta como se fosse a variável cujo endereço lhe foi atribuído.

Mas não podes atribuir a um apontador o valor retornado por uma função que retorna uma referência.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora