sábado, 10 de janeiro de 2009

Atributos privados onde?

Os programadores de Java e C++ pregam vigorosamente a favor de métodos e atributos privados, como se isso fosse uma grandíssima vantagem.

É um recurso… faz sentido em seu contexto, mas não traz vantagem alguma por si só – ao contrário da evangelização dos fanáticos.

De qualquer forma, o C++ não bloqueia tanto o acesso do programador quanto é pregado.

Por exemplo, voltemos lá atrás no artigo Portanto GDBM para Lua: havia uma classe GdbmObject com um descritor de arquivo de banco de dados privado.

Digamos que, por alguma razão bizarra, queiramos ter acesso direto ao descritor.

Mas o atributo é privado!

Vamos ao bacalhau:
class GdbmObjectCorrupting {
public:
bool closed;
GDBM_FILE fd;
}


Repare que os atributos públicos aqui têm o mesmo tipo e o mesmo nome dos atributos privados da classe original. Isso garantirá que os símbolos gerados sejam idênticos – e este é o truque.

Agora imagine que temos a instância obj de GdbmObject, da qual queremos acessar os atributos privados. A mágica é:
GdbmObjectCorrupting *aux =
reinterpret_cast<GdbmObjectCorrupting *>(obj);


Pronto! Já está feito o bacalhaua a mágica!

No escopo de aux, aux->fd dá acesso direto ao descritor de obj, assim como aux->closed dá acesso ao booleano closed de obj.

Agora, este artigo é uma prova de conceito! Não aconselho ninguém a fazer isso. Aliás o Kodumaro desaprova fortemente tal prática: reitero, é apenas uma prova de conceito.

[]'s
Cacilhas, La Batalema

11 comentários:

Victor Bogado disse...

Bacalhau se pode fazer em qualquer linguagem, porém o bom programador vai tentar reduzir o uso dos tais.

A questão dos "privados" e "públicos" é bem simples na verdade, uma classe expõem ao usuário dela uma certa API publica e a implementação fica (por principio) inacessível. Qual a vantagem? Caso seja necessário mudar a implementação é possível fazer-lo sem tocar em nenhum outro fonte, e dependendo da arquitetura até mesmo sem recompilar nada além da classe.

Ou seja o importante não é a "feature" de ter membros privados e sim a possibilidade de separar os detalhes de implementação do resto da classe.

"By the Way" este bacalhau que você fez não está correto, no estrito senso da linguagem. O que você fez pode funcionar em um dado compilador e voar feiamente em outro, pois o padrão do C++ não define como o compilador vai fazer o "layout" dos membros na memória, de forma que a posição do membro 'fd' pode ser diferente na sua classe e na classe original.

Sem contar que ao acessar o membro privado você pode estar perdendo a compatibilidade futura, imagine que a nova versão do "GdbmObject" resolva usar um "memory map" no lugar de um "file descriptor" para acessar o arquivo, o seu programa não vai mais funcionar ou sequer poder ser adaptado pois ele está acessando um detalhe de implementação.

La Batalema Pitonisto disse...

Sim, Victor.

Como eu disse, é uma prova de conceito. Não há em momento algum a intenção de incentivar esse tipo de prática.

Só demonstra como as coisas podem não funcionar como seus criadores esperavam.

[]'s
Cacilhas, La Batalema

tecggualberto disse...

realmente as coisas não sai do jeito que aprendemos na cartilha mas eu me importo em aprender as coisas da maneira mais primitiva pra quando o vaião cair ter sempre o truque na manga ,mas fora isso e bom seguir a cartilha

Walter Cruz disse...

Hehehe.. sempre tem um jeito de fuçar, que massa :)

Claudio disse...

Para mim o interessante é a idéia do encapsulamento. Se a linguagem permite acesso ou não a atributos/métodos privados, para mim isso é irrelevante.

La Batalema Pitonisto disse...

Finalmente alguém entendeu a brincadeira!

[]'s
Cacilhas, La Batalema

Guilherme Gall disse...

Achei interessante isso porque já ouvi tanta gente enaltecendo o bloqueio à métodos e atributos privados, que considerei esse recurso por um tempo uma propriedade essencial das "linguagens OO".

Já ouvi inclusive alguns o listarem como uma propriedade do paradigma de orientação a objetos.

Coincidentemente ou não, passei a enxergar isso como apenas um recurso (útil até, mas apenas um recurso) e a perceber que OO é sobre encapsulamento e colaboração entre objetos quando comecei a estudar Python.

--

Esse blog tem um feed para os comentários? Se tem eu não achei o link...

La Batalema Pitonisto disse...

Olá Guilherme!

Na verdade o essencial da orientação a objetos é a troca de mensagens entre objetos, característica muito ignorada pelos atuais defensores da OO.

O encapsulamento também é importante.

Tudo mais são recursos peculiares dessa ou daquela linguagem. Úteis sim, indispensáveis não.

Achei muito pertinente seu comentário.

Agora quanto a um feed de comentários, nunca pensamos em habilitar um, mas gostei da ideia.

Preciso agora descobrir se e como o blogger.com permite isso.

[]'s
Cacilhas, La Batalema

La Batalema Pitonisto disse...

Ops!

Faltou dizer que encapsulamento não é ocultação.

[]'s

Francisco Antônio da Silva Souza disse...

Esta questão de privado e público é sempre polêmica, principalmente quando se fala de Python.

Quanto a falar que encapsulamento não é ocultação, acho que não era o contexto do artigo, não tinha nada a ver.

Na verdade, foi dito que encapsulamento não é ocultação, mas não de forma explícita.

La Batalema Pitonisto disse...

Olá Francisco!

Essa questão sobre atributos e métodos privados e públicos só se tornou polémica devido à evangelização.

Se vista como realmente é – um recurso que faz sentido em seu contexto –, não há por que complicar.

Quanto a encapsulamento e ocultação, eu escrevi o artigo e eu digo que tem a ver sim.

Justamente a desinformação causada pela evangelização a favor desse recurso leva as pessoas a confundirem encapsulamento e ocultação.

E o artigo tem justamente a intenção de cutucar essa ferida.

Poderia simplesmente ter dito que orientação a objetos é em essência troca de mensagens e encapsulamento, e ocultação é um conceito diferente que algumas pessoas associam a encapsulamento, apesar de não ser a mesma coisa. Mas aí não seria tão divertido!

De qualquer forma, como você mesmo citou, isso ficou implícito no artigo.

[]'s
Cacilhas, La Batalema