Tag Archives: accessors

C/C++: Accessors(getters) e mutators(setters) de forma fácil usando macros

Continuando

Anteriormente, acho que até o ultimo post que eu fiz, falei sobre accessors(getters) e mutators(setters).

Isso foi a algum tempo atrás, e apesar de ser uma maneira muito elegante, ainda é uma maneira um pouco repetitiva, no sentido que você deve se preocupar e repetir algumas partes do processo. Isso é uma parte do processo que pode ser feita de forma automática, com muitas vantagens, com uma ajudinha de macros.

Estava vendo que o Murilo fez algo de forma parecida, e achei muito interessante. Resolvi copiar e alterar para o modo como eu mostrei em meu post passado, e mudei algumas coisas, como o nome de “declare” para “declare_am”, só para fica mais explicito….

Vejam agora que toda vez que eu quiser declarar uma variável data do tipo inteiro com getters e setters, é só usar declare_am(int,data)! Muito fácil.

Segue o código abaixo, usem para facilitar a vida, e qualquer discussão estamos ai :].

#include	<iostream>
#include	<cstdlib>

#define declare_am(type, name) \
private: type _##name; \
public: \
void name(const type& var){\
	_##name = var;\
}\
\
const type & name(){\
	return _##name; \
}\

class Teste_accessor_mutator{
	declare_am(int,data);
	declare_am(int,x);
	declare_am(int,y);
};

int main( int argc, char *argv[] ){
	Teste_accessor_mutator teste;

	teste.data(100);
	teste.x(1);
	teste.y(2);
	std::cout << teste.data() << std::endl ;
	std::cout << teste.x() << std::endl ;
	std::cout << teste.y() << std::endl ;
	return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */


C/C++: Accessors(getters) e mutators(setters) de um jeito diferente

Para que serve mutators e accessors?

Quando temos algum atributo em um objeto, esse atributo pode ser acessado e modificado para descobrir o estado do objeto.

Só que com o tempo, pode se fazer necessário que você tenha um maior controle no acesso a estados do objeto, para ter ou caso você queira um encapsulamento maior(Cache? Controle de acesso? Se que sabe 😉 ).

Com relação aos dados, existem duas operações possíveis para o acesso a um atributo do objeto, você pode acessar ou mudar o atributo. Com isso, você pode inserir uma camada nessas duas operações para poder ter esse encapsulamento a mais.

Já que sabemos o que fazer, então temos uma decisão aqui para tomar: Como iremos fazer isso? Existem algumas formas de se fazer isso, mas existe uma que utiliza polimorfismo em C++ que é mais particularmente interessante.

Ah, para quem ainda não entendeu ainda, os getters e setters servem como um estilo de implementar os accessor e mutators.

Como fazer em C++?

Cenário, dado que temos uma classe chamada Teste_accessor_mutator, que tem um atributo chamado _data. Esse atributo tem que ter um accessor chamado data e um mutator chamado data. Vamos ver isso em código implementado e um exemplo de acesso e mudança de atributo:

#include	<iostream>
#include	<cstdlib>

class Teste_accessor_mutator{
	private:
		int _data;
	public:
		const int &data(){
		return _data;
	}
	void data( const int &data ){
		_data=data;
	}
};

int main( int argc, char *argv[] ){
	Teste_accessor_mutator teste;

	teste.data(100);
	std::cout << teste.data() << std::endl ;
	return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */

Pronto, com isso temos um getter e setter implementado! Perai, calma lá.

Porque eu usei _data como nome do atributo? Porque apesar de de C++ suportar polimorfismo, ele suporta polimorfismo entre métodos e não atributos. Como não vai ser usado o atributo a não ser internamente em raras ocasiões apenas colocar underline(_) na frente do atributo para mudar o nome não causa uma perda de visibilidade muito grande.

Além dessa alternativa, poderia ser qualquer outro nome no dado, como  por exemplo o atributo se chamar m_data. Mas esse estilo tem uma visibilidade boa e não difere do original, então é bem aceitável.

Porque não usar um get_data e um set_data? Não que seja um estilo ruim, mas os nomes dos métodos ficam um pouco poluídos com essa abordagem. Se você tem a vantagem do polimorfismo, fica mais legível o código.


%d bloggers like this: