Encapsulamento C++

230 views
Skip to first unread message

CronosTs

unread,
Aug 4, 2012, 8:05:39 PM8/4/12
to ccppb...@googlegroups.com
Oi tudo bem ?

Então, minha duvida é a seguinte. O encapsulamento é realmente necessário ? Se sim, quais os cenários ?

Pergunto isso porque vejo classes e classes, tanto em exemplos que vejo na internet até em projetos hospedados nos sites de hospedagem de codigos tipo: google code e github. Nesses exemplos sempre vejo os Setters e os Getters, que basicamente fazem o que foram criados para fazer. A questão é: È realmente necessário isso ? Se eu tenho uma classe A que tem atributos e esses atributos são acessados e alterados pelos Getters e Setters da mesma forma que seriam se fossem publicos. Tipo:

Class A
{
    public:

        void Set(int bb){b = bb;}
        int Get(){return b;}

    private:

        int b;
};


Nesse caso, não vejo necessidade de um encapsulamento. Então tirando alguns caso como os que checam os valores antes de atribuir, quais são os casos em que isso é realmente necessário ? Porque a meu ver isso lota a classe com coisas inúteis. Em resumo: Getters e Setters devem ser usados apenas em alguns casos, correto ?

Уθя¡ςκ

unread,
Aug 4, 2012, 8:14:44 PM8/4/12
to ccppb...@googlegroups.com
Esse caso específico de setter/getter é mencionado no livro Clean Code do Uncle "Bob" Martin, e ele opina de forma curta e grossa que é inútil, muitas vezes se liga o modo automático na hora de adotar boas práticas sem uso do bom-senso, muitos dos getters/setters nunca serão de valia de fato.

Уθя¡ςκ

unread,
Aug 4, 2012, 8:38:47 PM8/4/12
to ccppb...@googlegroups.com

Do livro:

Origem do slide: aqui


Ponto V! - Vinícius Godoy

unread,
Aug 4, 2012, 8:40:21 PM8/4/12
to ccppb...@googlegroups.com
Oi.

O problema é: Como saber que esse valor se manterá sem validação no futuro? Ou que o tipo de dado não irá mudar de repente? 
Ou mesmo que você não substituir totalmente sua implementação atual por uma outra, ou por uma lib no futuro?

Muitas boas práticas preveem modificações futuras do software e preveem também que você está trabalhando em equipe. 

Com encapsulamento, o "mundo" dentro da sua classe é seu. Sem ele, você fica preso ao que as pessoas fora de sua classe fizeram com ela.

Att,

Vinícius


--
Antes de enviar um e-mail para o grupo leia:
http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo
para Eventos do Grupo C & C++ Brasil:
http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira: vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en

Thiago Adams

unread,
Aug 4, 2012, 8:40:46 PM8/4/12
to ccppb...@googlegroups.com


On Saturday, August 4, 2012 9:05:39 PM UTC-3, CronosTs wrote:
Oi tudo bem ?

Então, minha duvida é a seguinte. O encapsulamento é realmente necessário ? Se sim, quais os cenários ?


Necessário é uma pergunta vaga. C++ é necessário?

O encapsulamento é uma das melhores coisas da orientação a objetos.
Imagine uma classe de data.

struct Data
{
 int dia;
 int mes,
 int ano;
};

Esta classe precisa de uma validação. O encapsulamento e OOP permitem você criar um tipo de dado
Data que protege seu estado interno aumentando a segurança, diminuindo a quantidade de código, pois você não precisa verificar o estado em cada lugar que usa a Data e aumenta a eficiência pois a classe Data pode garantir que sempre está em um estado válido evitando que seja preciso testar por este estado em cada uso.





CronosTs

unread,
Aug 5, 2012, 2:33:52 PM8/5/12
to ccppb...@googlegroups.com
Então dois pontos importantes foram mostrados aqui:

1 -  Variáveis que precisam de alguma espécie de validação, como no caso do dia, mês e ano.

2 - Prevenir futuros erros caso ocorra modificações internas na classe.

Então, com exceção do caso que citei acima, em que, tal prática torna-se desnecessária vocês recomendam o uso de Getters e Setters ?

Murilo Adriano

unread,
Aug 5, 2012, 3:00:21 PM8/5/12
to ccppb...@googlegroups.com
O ponto 2 não deixa que exista exceções. Sempre pode ser que algo mude internamente em suas classes e se quer manter isso transparente para o código que as utilizam (i.é não precisar modificar outras partes do código), assim manter uma interface de acesso encapsulando seus dados é *virtualmente* sempre uma boa prática em OOP.

Enviado via iPhone
--

Уθя¡ςκ

unread,
Aug 5, 2012, 3:05:34 PM8/5/12
to ccppb...@googlegroups.com
Não, pra mim o ponto mais importante é o apontado pelo tio Bob:

"Encapsulamento não é apenas uma questão de colocar camadas de funções sobre as variáveis.
Encapsulamento diz respeito as abstrações."

Getters e setters com frequência não passam apenas de uma camada trivial sobre as variáveis, sem que a classe em si não tenha uma abstração coesa do que ela quer representar, a qual muitas vezes, se construída de forma correta, não vai necessitar de getter ou setter de variável alguma.
Classes cheias de getters e setters são classes prostituídas, usados como um meio de maquiar a falta de encapsulamento pra resolver a necessidade de acesso de estado interno de forma fácil, já neste momento quebrando o "encapsulamento", muitas vezes desprovendo a classe da abstração adequada que ela deveria ter.

Pra mim a frase do Bob é boa, porque, ao invés de te dar uma receita de bolo, o faz pensar de forma crítica na hora de aplicar encapsulamento.

Thiago

unread,
Aug 5, 2012, 5:59:11 PM8/5/12
to ccppb...@googlegroups.com
--

Thiago

unread,
Aug 5, 2012, 6:07:50 PM8/5/12
to ccppb...@googlegroups.com
Sim, o objetivo principal é manter o invariante da classe.
Fora isso, no caso de um get/set básico o que você pode ganhar é saber que não precisa alterar a interface da classe caso de um momento para outro o get/set deixar de ser básico.
Também fica uma interface indiferente para uma função template por ex, se o get/set é virtual ou não.


On 5 Aug 2012, at 16:05, Уθя¡ςκ <obl...@gmail.com> wrote:

--

Thiago Adams

unread,
Aug 5, 2012, 10:32:39 PM8/5/12
to ccppb...@googlegroups.com
 
Outra diferença ao usar get/set é a separação da interface da classe e da sua representação interna.
Por exemplo, uma interface que retorna/seta bool poderia internamente usar bits.
Uma interface de classe com get/set é mais abstrata. Um get nao precisa nem ter um dado membro associado.
Já uma variável membro publica expõe a representação interna.



--
www.thradams.com

Wesley Mesquita

unread,
Aug 6, 2012, 9:00:10 AM8/6/12
to ccppb...@googlegroups.com
Bom dia, 

Dois motivos práticos para utilizar o encapsulamento: manutenção do código e facilitar processos de debug. 

2012/8/5 Thiago Adams <thiago...@gmail.com>

--
Antes de enviar um e-mail para o grupo leia:
http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo
para Eventos do Grupo C & C++ Brasil:
http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira: vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en



--
Wesley Mesquita
Computer Engineer
http://www.wesleymesquita.com
Mobile: +55 11 95249272

Marcelo Zimbres

unread,
Aug 6, 2012, 10:01:00 AM8/6/12
to ccppb...@googlegroups.com
Se o std::vector tivesse as funções "T std::vector::get_element(i) const " e " void std::vector::set_element(size_t i,const T& element)", será que alguém iria preferir-los em vez do tradicional operator[]?

Marcelo

Уθя¡ςκ

unread,
Aug 6, 2012, 10:05:50 AM8/6/12
to ccppb...@googlegroups.com
Fora isso, no caso de um get/set básico o que você pode ganhar ...

E o que você pode perder? (se for descuidado)
Meses depois você se da conta que na sua base de código se alojou uma farra com seus getters e setters, farra esta ocorrendo em diversos pontos, promovida de forma independente, por N máquinas de transformar café em código.
E aí você percebe como pensou pequeno. Agora, o que você deseja é ter pensado melhor no papel da classe e ter provido uma interface adequada que embutisse ao menos razoavelmente as operações inerentes ao seu uso, ao invés de getters e setters ( e.g. caso drástico, data1.getDay() > data2.getDay() && data1.getMonth() > data2.getMonth() && data1.getYear() > data2.getYear() ------> data1 > data2 ).
Você se dá conta que sua classe apesar dos "métodos", não passa de uma mera estrutura de dados.
Os getters e setters ainda fazem o grandessíssimo papel de permitir que ainda haja possíveis alterações para validação de entrada ou que a disposição do estado interno mude, porém, nada disso vai ajudar pra resolver a bola de lodo que se formou através dos seus usos e abusos.

Adriano dos Santos Fernandes

unread,
Aug 6, 2012, 10:09:06 AM8/6/12
to ccppb...@googlegroups.com
On 06/08/2012 11:01, Marcelo Zimbres wrote:
> Se o std::vector tivesse as fun��es "T std::vector::get_element(i)
> const " e " void std::vector::set_element(size_t i,const T& element)",
> ser� que algu�m iria preferir-los em vez do tradicional operator[]?
>
>
O operador � uma fun��o e n�o viola o encapsulamento. Acho que o
principal que est� sendo discutido � se os *fields* devem ficar ou n�o
livres para serem acessados.

Eu costumo criar os getters/setters triviais, exceto em classes privadas
(definidas dentro de um .cpp) e structs (que n�o tenham fun��es).


Adriano

Thiago A. Corrêa

unread,
Aug 6, 2012, 10:26:48 AM8/6/12
to ccppb...@googlegroups.com
Naquela palestra da Microsoft com o Bjarne e todos os outros Gurus foi
discutido isso, acho que no QA. Alguem que tenha o link na mão
certamente pode responder providenciando :)

Antigamente era um rule of thumb usar getter e setters. Hoje em dia,
já não é tão considerado assim como uma boa prática obrigatória. Com o
"surgimento"[1] do refactoring, tem ficado simples reorganizar o
código para encapsular um campo se necessário, e não é preciso
despender tempo encapsulando todos que provavelmente nunca serão
necessários.
Segundo essa lógica, a recomendação era de "Não se preocupe com isso"


[1] Não que tenha sido inventado recentemente, mas que foi melhor
compreendido pela literatura técnica e também presente nas
ferramentas.

Att.
Thiago A. Correa

Murilo Adriano

unread,
Aug 6, 2012, 10:31:33 AM8/6/12
to ccppb...@googlegroups.com
E tem. Não com esses nomes, mas tem. Inclusive ele faz bound checking.

Adriano dos Santos Fernandes

unread,
Aug 6, 2012, 10:34:45 AM8/6/12
to ccppb...@googlegroups.com
On 06/08/2012 11:26, Thiago A. Corr�a wrote:
> Naquela palestra da Microsoft com o Bjarne e todos os outros Gurus foi
> discutido isso, acho que no QA. Alguem que tenha o link na m�o
> certamente pode responder providenciando :)
>
> Antigamente era um rule of thumb usar getter e setters. Hoje em dia,
> j� n�o � t�o considerado assim como uma boa pr�tica obrigat�ria. Com o
> "surgimento"[1] do refactoring, tem ficado simples reorganizar o
> c�digo para encapsular um campo se necess�rio, e n�o � preciso
> despender tempo encapsulando todos que provavelmente nunca ser�o
> necess�rios.
> Segundo essa l�gica, a recomenda��o era de "N�o se preocupe com isso"
>
>
Aproveitando... Existe alguma IDE/ferramenta que faz refactoring
(digamos, apenas renomear um m�todo) de C++ corretamente?


Adriano

Thiago A. Corrêa

unread,
Aug 6, 2012, 10:42:46 AM8/6/12
to ccppb...@googlegroups.com
2012/8/6 Adriano dos Santos Fernandes <adri...@gmail.com>:

> Aproveitando... Existe alguma IDE/ferramenta que faz refactoring
> (digamos, apenas renomear um método) de C++ corretamente?
>

Visual Studio com Visual Assist funciona muito bem. Na hora de dar um
extrair metodo que as vezes ele se confunde com truques no namespace,
por exemplo ele quer que o metodo retorne um QT_NAMESPACE::QString ao
invéz de simplesmente QString. Mas renomear metodo vai com tudo.

No 2010 muita funcionalidade que só tinha no Visual Assist começou a
aparecer no IDE mas não tenho certeza se refatoração é uma delas.

Ponto V! - Vinícius Godoy

unread,
Aug 6, 2012, 12:00:44 PM8/6/12
to ccppb...@googlegroups.com
Cuidado: O encapsulamento de campos na forma de refatoração só é uma boa alternativa caso você não esteja programando uma lib. Caso contrário, encapsula-los irá quebrar o código de quem utiliza a lib. A ação não poderia nem sequer mais ser chamada de refatoração, afinal, o refactoring consiste na modificação do código sem alterar seu comportamento observável [1].

Quanto ao fato de chamar get e set: O nome "get" e "set" se popularizou por causa do padrão JavaBeans. Nesse padrão, esses nomes eram obrigatórios. O padrão surgiu antes do Java suportar o conceito de "annotations", por isso, era necessário um prefixo conhecido (get, set e is) para que um mecanismo de reflexão pudesse encontrar automaticamente as propriedades.

Eu acho o encapsulmento importante, mas muita gente confunde hoje em dia o conceito com "inserir get e set para tudo". Certa vez, inclusive, escrevi um longo post no GUJ sobre o assunto, para mostrar que a coisa não é tão simples assim: http://www.guj.com.br/java/104592-gets-sets-e-encapsulamento#564414

[]s,

Vinícius

P.

unread,
Aug 6, 2012, 12:14:44 PM8/6/12
to ccppb...@googlegroups.com

Em sábado, 4 de agosto de 2012 21h05min39s UTC-3, CronosTs escreveu:
 
Então, minha duvida é a seguinte. O encapsulamento é realmente necessário ?

Sim.
 
Se sim, quais os cenários ?

No cenário onde o desacoplamento entre o objeto referente e o objeto referenciado é útil.

--
 P.

P.

unread,
Aug 6, 2012, 12:18:03 PM8/6/12
to ccppb...@googlegroups.com


Em segunda-feira, 6 de agosto de 2012 11h01min00s UTC-3, mzimbres escreveu:
Se o std::vector tivesse as funções "T std::vector::get_element(i) const " e " void std::vector::set_element(size_t i,const T& element)", será que alguém iria preferir-los em vez do tradicional operator[]?

Veja std::vector<T>::at .

--
 P.

P.

unread,
Aug 6, 2012, 12:19:55 PM8/6/12
to ccppb...@googlegroups.com

Em segunda-feira, 6 de agosto de 2012 11h34min45s UTC-3, Adriano dos Santos Fernandes escreveu:
On 06/08/2012 11:26, Thiago A. Corr�a wrote:
> Naquela palestra da Microsoft com o Bjarne e todos os outros Gurus foi
> discutido isso, acho que no QA. Alguem que tenha o link na m�o
> certamente pode responder providenciando :)
>
> Antigamente era um rule of thumb usar getter e setters. Hoje em dia,
> j� n�o � t�o considerado assim como uma boa pr�tica obrigat�ria. Com o
> "surgimento"[1] do refactoring, tem ficado simples reorganizar o
> c�digo para encapsular um campo se necess�rio, e n�o � preciso
> despender tempo encapsulando todos que provavelmente nunca ser�o
> necess�rios.
> Segundo essa l�gica, a recomenda��o era de "N�o se preocupe com isso"
>
>
Aproveitando... Existe alguma IDE/ferramenta que faz refactoring
(digamos, apenas renomear um m�todo) de C++ corretamente?

Eclipse CDT ; Visual Studio 2010 +  Visual Assist X .

--
 P.

Marcelo Zimbres

unread,
Aug 6, 2012, 1:43:45 PM8/6/12
to ccppb...@googlegroups.com
" Veja std::vector<T>::at  "

Bem, eu conheço o at(), mas eu me referi a um setter como é implementado normalmente, com retorno "void", que não retorne referência para os internos da classe.

Marcelo

--

Thiago Adams

unread,
Aug 6, 2012, 3:14:29 PM8/6/12
to ccppb...@googlegroups.com
2012/8/6 Marcelo Zimbres <mzim...@gmail.com>:
> " Veja std::vector<T>::at "
>
> Bem, eu conheço o at(), mas eu me referi a um setter como é implementado
> normalmente, com retorno "void", que não retorne referência para os internos
> da classe.
>


O std::vector , propositalmente quer dar o acesso ao elemento do array.
Posso fazer isso por ex.
&m_v[0]

Murilo Adriano Vasconcelos

unread,
Aug 6, 2012, 4:29:33 PM8/6/12
to ccppb...@googlegroups.com
Em 6 de agosto de 2012 14:43, Marcelo Zimbres <mzim...@gmail.com> escreveu:
" Veja std::vector<T>::at  "

Bem, eu conheço o at(), mas eu me referi a um setter como é implementado normalmente, com retorno "void", que não retorne referência para os internos da classe.

Talvez o seu "normalmente" é porque quando a gente lembra de getters/setters a gente lembra "normalmente" de Java, que não tem suporte a esse tipo de construção (retorno de referências). Na minha opinião essa forma de usar (do at()) quando aplicável é melhor por simplificar a interface. A minha pergunta é: por que não fazer assim?

--
Murilo Adriano Vasconcelos

Marcelo Zimbres

unread,
Aug 6, 2012, 4:45:46 PM8/6/12
to ccppb...@googlegroups.com
Eu nunca programei em java e também nunca vi setter que retornasse diferente de void, acho que essa é uma prática comum em C++. E sim, é extremamente conveniente expor seus internos com retorno do tipo const T&.

"O std::vector , propositalmente quer dar o acesso ao elemento do array.
Posso fazer isso por ex.
&m_v[0]"

Eu sugeri alguma coisa em outra direção?

Marcelo

CronosTs

unread,
Aug 6, 2012, 4:57:30 PM8/6/12
to ccppb...@googlegroups.com
Obrigados a todos que responderam tiraram muitas dúvidas e me abriram a mente! Agradecimentos especiais a ViniGodoy pelo link muitíssimo instrutivo.

Thiago Adams

unread,
Aug 6, 2012, 4:57:48 PM8/6/12
to ccppbrasil


On Aug 6, 5:45 pm, Marcelo Zimbres <mzimb...@gmail.com> wrote:
> Eu nunca programei em java e também nunca vi setter que retornasse
> diferente de void, acho que essa é uma prática comum em C++. E sim, é
> extremamente conveniente expor seus internos com retorno do tipo const T&.
>
> "O std::vector , propositalmente quer dar o acesso ao elemento do array.
> Posso fazer isso por ex.
> &m_v[0]"
>
> Eu sugeri alguma coisa em outra direção?

Não sei se entendi a sua questão.
Tentei responder a seguinte pergunta:

>Se o std::vector tivesse as funções "T std::vector::get_element(i) const "
>e " void std::vector::set_element(size_t i,const T& element)", será que
>alguém iria preferir-los em vez do tradicional operator[]?

Se é do design do vector ter todo acesso (escrita/leitura) via
operator [] não faria mais sentido tentar proteger com set_element e
get_element pois já existe a versão menos encapsulada.



Murilo Adriano Vasconcelos

unread,
Aug 6, 2012, 5:13:55 PM8/6/12
to ccppb...@googlegroups.com
Em 6 de agosto de 2012 17:45, Marcelo Zimbres <mzim...@gmail.com> escreveu:
Eu nunca programei em java e também nunca vi setter que retornasse diferente de void, acho que essa é uma prática comum em C++. E sim, é extremamente conveniente expor seus internos com retorno do tipo const T&.

"O std::vector , propositalmente quer dar o acesso ao elemento do array.
Posso fazer isso por ex.
&m_v[0]"

Eu sugeri alguma coisa em outra direção?

Se a pergunta é se eu usaria eu diria que não. std::vector<> de certa forma implementa através do operador [] semântica de arrays. Eu quero usar std::vector<> como um array pois é o objetivo dele prover essas facilidades.

Agora pra outras coisas, depende do caso. Abusar de sobrecarga de operadores já é uma polêmica muito grande há muito tempo. Quando encontro um claro significado para um operador como no caso do std::vector<> eu prefiro utilizá-lo. Caso contrário *e* quando há necessidade de prover acesso a propriedades da minha classe, utilizar getters/setters é a solução mais adequada. No entanto eu não gosto desses prefixos get e set.

Abraço

--
Murilo Adriano Vasconcelos

Vinícius Godoy de Mendonça

unread,
Aug 6, 2012, 10:18:32 PM8/6/12
to ccppb...@googlegroups.com

Opa. Obrigado.

Em 06/08/2012 17:57, "CronosTs" <cron...@gmail.com> escreveu:
Obrigados a todos que responderam tiraram muitas dúvidas e me abriram a mente! Agradecimentos especiais a ViniGodoy pelo link muitíssimo instrutivo.

--

Thiago Adams

unread,
Aug 8, 2012, 8:23:33 AM8/8/12
to ccppbrasil


On Aug 6, 6:13 pm, Murilo Adriano Vasconcelos
....
> mais adequada. No entanto eu não gosto desses prefixos get e set.

Eu também prefiro não usar, mas depende.
Por exemplo, faz bastante sentido no vector ter
resize(tamanho) e size() ao invés de getsize, setsize.

O "set" neste caso é um verbo relativo a transformação de estado e o
"get" é simplesmente um substantivo referente ao estado.

Mas tem outras situações como

window.title
window.title()

Que se fosse seguir a mesma lógica seria ChangeTitle() e neste caso
acabo usando SetTitle mesmo.


P.

unread,
Aug 8, 2012, 10:26:14 AM8/8/12
to ccppb...@googlegroups.com, mur...@clever-lang.org
Em segunda-feira, 6 de agosto de 2012 17h29min33s UTC-3, Murilo Adriano Vasconcelos escreveu:
Em 6 de agosto de 2012 14:43, Marcelo Zimbres <mzim...@gmail.com> escreveu:
" Veja std::vector<T>::at  "

Bem, eu conheço o at(), mas eu me referi a um setter como é implementado normalmente, com retorno "void", que não retorne referência para os internos da classe.

Talvez o seu "normalmente" é porque quando a gente lembra de getters/setters a gente lembra "normalmente" de Java, que não tem suporte a esse tipo de construção (retorno de referências).

Não há qualquer diferença entre este "normalmente" e o "normalmente" do Java; os getters do Java certamente retornam referências se o tipo não for primitivo, e os setters do Java tipicamente retornam void.

--
 P.

Murilo Adriano Vasconcelos

unread,
Aug 8, 2012, 2:34:11 PM8/8/12
to ccppb...@googlegroups.com
Olá,
Realmente eu escrevi muito mal essa parte. Eu quis dizer que em C++ é comum a gente fazer:

...
T& something() { return this->s; }
...

obj.something() = x; // setter
x = obj.something(); // getter

Ou seja, a mesma função-membro tem duas utilidades que nem o at() do std::vector<>.

Ponto V! - Vinícius Godoy

unread,
Aug 8, 2012, 3:42:31 PM8/8/12
to ccppb...@googlegroups.com
Mas essa forma não viola igualmente o encapsulamento?

Minha dúvida sempre foi:
Você não pode retornar uma referência para algo que seja diferente do tipo da sua propriedade interna. Além disso, esse "set" não faz qualquer validação e, principalmente, não permite que se faça isso no futuro.

Então, isso não é apenas uma maneira rebuscada de deixar o tipo público?


Murilo Adriano Vasconcelos

unread,
Aug 8, 2012, 5:32:35 PM8/8/12
to ccppb...@googlegroups.com

Olá,


Em 8 de agosto de 2012 16:42, Ponto V! - Vinícius Godoy <vini...@pontov.com.br> escreveu:
Mas essa forma não viola igualmente o encapsulamento?

Minha dúvida sempre foi:
Você não pode retornar uma referência para algo que seja diferente do tipo da sua propriedade interna. Além disso, esse "set" não faz qualquer validação e, principalmente, não permite que se faça isso no futuro.

Então, isso não é apenas uma maneira rebuscada de deixar o tipo público?

Não exatamente. É possível "proteger" seu objeto/adicionar lógica como outra função-membro faria. 
Como eu disse anteriormente por exemplo, o std::vector<>::at(size_t idx) faz bound checking retornando uma exceção se "idx >= size()".
Claro que como já foi discutido é melhor ter o par, mas gosto de usar esse recurso quando aplicável. 
No final, é tudo uma questão de bom senso :)

Abraço,

Murilo Adriano Vasconcelos

unread,
Aug 8, 2012, 5:34:33 PM8/8/12
to ccppb...@googlegroups.com
Em 8 de agosto de 2012 18:32, Murilo Adriano Vasconcelos <mur...@clever-lang.org> escreveu:

Claro que como já foi discutido é melhor ter o par, mas gosto de usar esse recurso quando aplicável. 

[SIC]
Claro que, como já foi discutido, *em muitos casos* é melhor ter o par, mas gosto de usar esse recurso quando aplicável.  

Vinícius Godoy de Mendonça

unread,
Aug 8, 2012, 8:35:12 PM8/8/12
to ccppb...@googlegroups.com

Sim, mas você fez só a validação do idx, não do dado de entrada. Se surgir alguma restrição a esse dado, como  ter que ser positivo, ou se tiver que mudar seu tipo interno, dançou. Em termos do dado em si, é praticamente como publica-lo.

Felipe Magno de Almeida

unread,
Aug 8, 2012, 8:44:28 PM8/8/12
to ccppb...@googlegroups.com
2012/8/8 Ponto V! - Vinícius Godoy <vini...@pontov.com.br>:
> Mas essa forma não viola igualmente o encapsulamento?
>
> Minha dúvida sempre foi:
> Você não pode retornar uma referência para algo que seja diferente do tipo
> da sua propriedade interna. Além disso, esse "set" não faz qualquer
> validação e, principalmente, não permite que se faça isso no futuro.
>
> Então, isso não é apenas uma maneira rebuscada de deixar o tipo público?

A referência tem outro problema que é o de obrigar a implementação da classe
a manter o dado 'stored' exatamente com esse mesmo tipo. Isso é terrível
para os associative containers aonde o iterador retorna uma referência
para um std::pair ! Ou seja, você precisa manter a chave e o elemento
guardados sempre por std::pair para implementar essa interface.

[snip]

[]'s
--
Felipe Magno de Almeida

Eric Chiesse

unread,
Aug 13, 2012, 12:51:06 PM8/13/12
to ccppb...@googlegroups.com
Cara, esse tipo de coisa tem que ser usada com muita parcimônia.

Primeiro que atribuir a uma chamada de função é sintaticamente feio (minha opinião).
Segundo que é obscuro, pois normalmente não se espera esse tipo de construção.
E terceiro que é uma grande chance de quebrar o encapsulamento sem querer.

Tirando a sobrecarga do operador de índice ([]) e de stream insertion/extraction (>> e <<) usar esse tipo de recurso tem que ser pensado com carinho.

---
Eric
br.linkedin.com/in/echiesse



P.

unread,
Aug 14, 2012, 4:20:50 PM8/14/12
to ccppb...@googlegroups.com, mur...@clever-lang.org
Em quarta-feira, 8 de agosto de 2012 15h34min11s UTC-3, Murilo Adriano Vasconcelos escreveu:
 
Realmente eu escrevi muito mal essa parte. Eu quis dizer que em C++ é comum a gente fazer:

...
T& something() { return this->s; }
...

obj.something() = x; // setter
x = obj.something(); // getter


O nível de encapsulamento aqui é mínimo -- mas não é zero, e permite a reordenação dos membros de classe sem quebrar ABI. Nunca vi isso nas trincheiras, porém.

--
 P.
Reply all
Reply to author
Forward
0 new messages