<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Objectzilla &#187; C++</title>
	<atom:link href="http://www.objectzilla.com.br/category/sem-categoria/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.objectzilla.com.br</link>
	<description>por Leonardo Veríssimo</description>
	<lastBuildDate>Sat, 05 Jun 2010 18:58:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Closure: em C++ (?)</title>
		<link>http://www.objectzilla.com.br/2009/01/07/closure-em-cpp/</link>
		<comments>http://www.objectzilla.com.br/2009/01/07/closure-em-cpp/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 00:44:39 +0000</pubDate>
		<dc:creator>Leonardo</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.objectzilla.com.br/?p=29</guid>
		<description><![CDATA[Esse post é uma continuação da série Closure.
C++ tem closure? Como assim? Viajou, né? Bom, vou tentar fazer algo, só não sei se vai dar certo. A minha idéia é fazer uma classe Observer onde é possível registrar uma closure. Quando for chamado a função notify() do objeto dessa classe, a closure será chamada e [...]]]></description>
			<content:encoded><![CDATA[<p><em>Esse post é uma continuação da série <a href="http://www.objectzilla.com.br/2009/01/04/voce-sabe-o-que-e-closure/">Closure</a></em>.</p>
<p>C++ tem closure? Como assim? Viajou, né? Bom, vou <em>tentar</em> fazer algo, só não sei se vai dar certo. A minha idéia é fazer uma classe <strong>Observer</strong> onde é possível registrar uma closure. Quando for chamado a função <strong>notify()</strong> do objeto dessa classe, a closure será chamada e esta terá inclusive referencia de um contexto que não existe pro objeto Observer.<span id="more-29"></span></p>
<p>Primeiro, criei a classe <strong>SimpleObserver</strong> (pois só armazena uma closure por vez e não se aproveita de template). Todo o conteúdo do fonte está em um arquivo hpp (simple_observer.hpp):</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef _SIMPLE_OBSERVER_H_</span>
<span style="color: #339900;">#define _SIMPLE_OBSERVER_H_</span>
&nbsp;
<span style="color: #339900;">#include &lt;boost/function.hpp&gt;</span>
&nbsp;
<span style="color: #0000ff;">class</span> SimpleObserver <span style="color: #008000;">&#123;</span>
&nbsp;
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
        <span style="color: #ff0000; font-style: italic;">/* armazena uma função sem parâmetros que retorna void */</span>
        <span style="color: #0000ff;">void</span> registry<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">function</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> cb<span style="color: #008000;">&#41;</span>     <span style="color: #008000;">&#123;</span> callback <span style="color: #000080;">=</span> cb<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #ff0000; font-style: italic;">/* invoca a função previamente armazenada */</span>
        <span style="color: #0000ff;">void</span> notify<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>                                             <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>callback<span style="color: #008000;">&#41;</span> callback<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>    <span style="color: #008000;">&#125;</span>  
&nbsp;
    <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">function</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span> callback<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif</span></pre></div></div>

<p>Simples, não? Um método pra armazenar uma função, outro pra chamá-lo. Repare que eu usei uma classe do Boost, <strong>function</strong>, que serve para guardar funções de qualquer tipo. No caso limitei para retorno void e nada de parâmetro de entrada. Outra coisa, pra quem não conhece C++, a expressão <strong>if(callback)</strong> parece estranho. O que ocorre é que nessa linguagem, é possível um objeto ser implicitamente convertido pra outro tipo (contanto que o programador escreva a função de conversão, claro!), e, no nosso caso, a biblioteca converte o objeto function pra um outro do tipo bool. &#8220;Mas pra que?&#8221;, você pensa. Bom, é comum um objeto inválido ser sempre convertido como false, e um válido como true; e nesse caso, o objeto é inválido se o objeto function não apontar pra nenhum ponteiro de função.</p>
<p>Agora, vou mostrar a classe que vai criar uma closure, a <strong>Event</strong>, em dois arquivos, a event.hpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef _EVENT_H_</span>
<span style="color: #339900;">#define _EVENT_H_</span>
&nbsp;
<span style="color: #339900;">#include &lt;map&gt;</span>
<span style="color: #339900;">#include &lt;boost/function.hpp&gt;</span>
&nbsp;
<span style="color: #0000ff;">class</span> Event <span style="color: #008000;">&#123;</span>
&nbsp;
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
        <span style="color: #ff0000; font-style: italic;">/* construtor que recebe um número como argumento */</span>
        Event<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">long</span><span style="color: #000040;">&amp;</span> value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #ff0000; font-style: italic;">/* retorna uma função, que leva em consideração o valor de entrada
           e a própria instância */</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">function</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span> create_closure<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">map</span><span style="color: #000080;">&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span>, <span style="color: #0000ff;">long</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> parameter_value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #0000ff;">long</span> instance_value<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>inst_value<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
        <span style="color: #0000ff;">void</span> callback_function<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">map</span><span style="color: #000080;">&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span>, <span style="color: #0000ff;">long</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">*</span> param, <span style="color: #0000ff;">long</span> local<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
        <span style="color: #0000ff;">long</span> inst_value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif</span></pre></div></div>

<p>É uma classe que tem um construtor que recebe um valor (daqui a pouco você vai ver que esse valor é atribuído à única variável de instância da classe). A função <strong>create_closure()</strong> retorna uma &#8220;function&#8221; recebendo um map. A função <strong>instance_value()</strong> simplesmente mostra o valor da variável de instância. Existe uma função privada, a <strong>callback_function</strong> que usarei como ponteiro da minha closure.</p>
<p>Vamos à event.cpp:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &quot;event.hpp&quot;</span>
<span style="color: #339900;">#include &lt;boost/bind.hpp&gt;</span>
&nbsp;
Event<span style="color: #008080;">::</span><span style="color: #007788;">Event</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">long</span><span style="color: #000040;">&amp;</span> value<span style="color: #008000;">&#41;</span>
    <span style="color: #008080;">:</span> inst_value<span style="color: #008000;">&#40;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
boost<span style="color: #008080;">::</span><span style="color: #007788;">function</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span>
Event<span style="color: #008080;">::</span><span style="color: #007788;">create_closure</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">map</span><span style="color: #000080;">&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span>, <span style="color: #0000ff;">long</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> parameter<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
    <span style="color: #0000ff;">long</span> local_value <span style="color: #000080;">=</span> parameter<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">&quot;value&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #000040;">+</span> <span style="color: #0000dd;">5</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">bind</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>Event<span style="color: #008080;">::</span><span style="color: #007788;">callback_function</span>, <span style="color: #0000dd;">this</span>, <span style="color: #000040;">&amp;</span>parameter, local_value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> 
Event<span style="color: #008080;">::</span><span style="color: #007788;">callback_function</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">map</span><span style="color: #000080;">&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span>, <span style="color: #0000ff;">long</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">*</span> param, <span style="color: #0000ff;">long</span> local<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>param<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">&quot;value&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #000040;">+</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">6</span><span style="color: #008080;">;</span>
    this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>inst_value <span style="color: #000040;">+</span><span style="color: #000080;">=</span> local<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>A função create_closure() faz uma soma qualquer, criando uma variável local. Depois é usado o <strong>bind()</strong>, também do Boost, para reduzir uma função com três parâmetros (o &#8220;this&#8221; mais os dois parâmetros &#8220;normais&#8221;) para uma função com zero parâmetros. Essa função, a <strong>callback_function</strong>, não faz nada mais do que um cálculo.</p>
<p>Pra finalizar, criei o arquivo main.cpp com a função que chama todo mundo:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &quot;simple_observer.hpp&quot;</span>
<span style="color: #339900;">#include &quot;event.hpp&quot;</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">**</span> argv<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
    SimpleObserver observer<span style="color: #008080;">;</span>
&nbsp;
    Event event<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    std<span style="color: #008080;">::</span><span style="color: #007788;">map</span><span style="color: #000080;">&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span>, <span style="color: #0000ff;">long</span><span style="color: #000080;">&gt;</span> parameter<span style="color: #008080;">;</span>
    parameter<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">&quot;value&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">8</span><span style="color: #008080;">;</span>
&nbsp;
    observer.<span style="color: #007788;">registry</span><span style="color: #008000;">&#40;</span> event.<span style="color: #007788;">create_closure</span><span style="color: #008000;">&#40;</span>parameter<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    observer.<span style="color: #007788;">notify</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Instance value = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> event.<span style="color: #007788;">instance_value</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Parameter      = &quot;</span> <span style="color: #000080;">&lt;&lt;</span> parameter<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">&quot;value&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Eu tenho o Ubuntu, e usei o apt-get pra pegar uma versão da biblioteca Boost e, obviamente, o g++. Como o gerenciador de pacotes vai colocar os HPPs num lugar visível, basta apenas executar o comando:</p>
<pre>
 c++ -O3 event.cpp main.cpp -o closure
</pre>
<p>Lá na método main, eu chamei tudo mundo, crio o observer, crio o objeto event, e peço a este um closure a ser passado para o observer. Quando o observer for notificado, a instância de event é alterado, assim como o parâmetro passado.</p>
<p>Mas repare uma coisa, eu menti para vocês! C++ não possui suporte a closures! Lá no método create_closure(), tive que passar o &#8220;contexto&#8221; (parâmetros, variáveis locais, a própria referência this) explicitamente com o &#8220;bind&#8221;. E por não ter garbage collector, não há nem garantia de que os objetos passados com bind realmente exista na sua execução. Portanto, nem tente fazer algo parecido.</p>
<p>Eu comecei com C++ porque é a &#8220;pior implementação de closures&#8221; das linguagens que eu conheço. Mas não se preocupe, <a href="http://www.objectzilla.com.br/2009/01/14/closure-em-java/">em um próximo post</a>, vou mostrar closure em uma outra linguagem, só que dessa vez, de verdade!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectzilla.com.br/2009/01/07/closure-em-cpp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
