<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Legacy Code on kenji.blog</title><link>http://kenji.blog/pt/tags/legacy-code/</link><description>Recent content in Legacy Code on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 20:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/tags/legacy-code/index.xml" rel="self" type="application/rss+xml"/><item><title>A Arte da Refatoração: Melhorando Código C++ Legado com Segurança</title><link>http://kenji.blog/pt/p/refactoring-legacy-cpp-code-safely/</link><pubDate>Sat, 12 Sep 2026 20:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/refactoring-legacy-cpp-code-safely/</guid><description>&lt;img src="http://kenji.blog/p/refactoring-legacy-cpp-code-safely/img/eyecatch.jpg" alt="Featured image of post A Arte da Refatoração: Melhorando Código C++ Legado com Segurança" />&lt;h1 id="a-arte-da-refatoração-melhorando-código-c-legado-com-segurança">A Arte da Refatoração: Melhorando Código C++ Legado com Segurança
&lt;/h1>&lt;p>Na moderna área de desenvolvimento de software, a batalha contra o &amp;ldquo;código legado&amp;rdquo; é inevitável. Especialmente na linguagem C++, o código legado representa uma ameaça incomparável à de outras linguagens. Gerenciamento de memória manual (uma tempestade de ponteiros brutos e &lt;code>new&lt;/code> / &lt;code>delete&lt;/code>), abuso de variáveis globais, falta de segurança contra exceções e, acima de tudo, o fato de que &amp;ldquo;não há testes&amp;rdquo;. Em sua obra clássica &amp;ldquo;Working Effectively with Legacy Code&amp;rdquo; (Trabalhando Eficazmente com Código Legado), Michael Feathers declarou firmemente: &amp;ldquo;Código sem testes é código legado.&amp;rdquo;&lt;/p>
&lt;p>Neste artigo, explicaremos exaustivamente, tanto na teoria quanto na prática, os segredos para migrar e refatorar de forma segura e confiável uma base de código C++ legado, acumulada ao longo de décadas, para o C++ Moderno (C++11/14/17/20). Abrangeremos abordagens práticas, começando com o modelo matemático da dívida técnica, passando pela separação segura de dependências e terminando com a purificação do código usando recursos modernos da linguagem.&lt;/p>
&lt;hr>
&lt;h2 id="1-complexidade-e-o-modelo-matemático-da-dívida-técnica">1. Complexidade e o Modelo Matemático da Dívida Técnica
&lt;/h2>&lt;p>Para justificar a refatoração, precisamos quantificar os problemas que a base de código atual enfrenta. A métrica mais comum para medir a complexidade estrutural do código é a &amp;ldquo;Complexidade Ciclomática (Cyclomatic Complexity)&amp;rdquo;. Esta complexidade é definida pela seguinte fórmula baseada na teoria dos grafos de fluxo de controle:&lt;/p>
$$ M = E - N + 2P $$&lt;p>Onde:&lt;/p>
&lt;ul>
&lt;li>$M$ é a complexidade ciclomática&lt;/li>
&lt;li>$E$ é o número de arestas do grafo (fluxo de processamento, transições)&lt;/li>
&lt;li>$N$ é o número de nós do grafo (blocos básicos de processamento)&lt;/li>
&lt;li>$P$ é o número de componentes conectados (geralmente $P=1$ para uma única função ou método)&lt;/li>
&lt;/ul>
&lt;p>À medida que a complexidade $M$ aumenta, o número de casos de teste necessários para testar exaustivamente a função aumenta de forma linear, ou, dependendo da combinação de ramificações condicionais, de forma exponencial. Além disso, existe uma regra empírica de que a probabilidade de ocorrer um bug $P(bug)$ aumenta exponencialmente com a complexidade $M$. Se modelarmos isso em uma forma semelhante à distribuição de Poisson, ficaria assim:&lt;/p>
$$ P(bug) = 1 - e^{-\lambda \cdot M} $$&lt;p>(Onde $\lambda$ é uma constante dependente da habilidade da equipe de desenvolvimento ou da dificuldade do domínio.)&lt;/p>
&lt;p>Além disso, o custo da dívida técnica cresce com juros compostos. Se a dívida técnica inicial for $C_0$ e a taxa de juros por iteração (a taxa de declínio da produtividade devido à dificuldade de alteração do código) for $r$, o custo de modificação $Cost(t)$ após o período $t$ pode ser expresso da seguinte forma:&lt;/p>
$$ Cost(t) = C_0 \times (1 + r)^t $$&lt;p>O que esta fórmula mostra claramente é a cruel realidade de que &amp;ldquo;ignorar o código legado leva a um aumento exponencial dos custos ao longo do tempo&amp;rdquo;. Portanto, a dívida precisa ser paga (refatorada) precocemente.&lt;/p>
&lt;hr>
&lt;h2 id="2-a-regra-absoluta-da-refatoração-test-first-testes-primeiro">2. A Regra Absoluta da Refatoração: &amp;ldquo;Test First&amp;rdquo; (Testes Primeiro)
&lt;/h2>&lt;p>O maior medo ao modificar código legado é: &amp;ldquo;Vou quebrar o comportamento normal existente (causar uma regressão)?&amp;rdquo;. A única forma de eliminar esse medo são os &amp;ldquo;testes automatizados&amp;rdquo;.&lt;/p>
&lt;p>No entanto, o código legado não possui testes em primeiro lugar. É aqui que se torna importante a introdução dos &amp;ldquo;Testes de Caracterização (Characterization Tests)&amp;rdquo;. Testes de caracterização são testes que registram o comportamento atual do sistema &amp;ldquo;exatamente como ele é&amp;rdquo;, em vez de &amp;ldquo;como ele deveria se comportar originalmente&amp;rdquo;.&lt;/p>
&lt;p>O fluxograma a seguir mostra o ciclo de vida de uma refatoração segura.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Identificar o código legado alvo&amp;#34;] --&amp;gt; B[&amp;#34;Escrever um teste de caracterização&amp;#34;]
B --&amp;gt; C[&amp;#34;Confirmar que todos os testes passam&amp;#34;]
C --&amp;gt; D[&amp;#34;Realizar pequenas refatorações&amp;#34;]
D --&amp;gt; E[&amp;#34;Executar os testes novamente&amp;#34;]
E -- &amp;#34;Falha (Red)&amp;#34; --&amp;gt; F[&amp;#34;Reverter as alterações (Revert)&amp;#34;]
F --&amp;gt; D
E -- &amp;#34;Sucesso (Green)&amp;#34; --&amp;gt; G[&amp;#34;Fazer o commit do código&amp;#34;]
G --&amp;gt; H{&amp;#34;Há mais pontos para melhorar?&amp;#34;}
H -- &amp;#34;Sim&amp;#34; --&amp;gt; D
H -- &amp;#34;Não&amp;#34; --&amp;gt; I[&amp;#34;Refatoração concluída&amp;#34;]
&lt;/pre>
&lt;p>Ao executar este ciclo, os desenvolvedores podem sempre modificar o código com uma rede de segurança. Se os testes falharem, é importante usar o &lt;code>Revert&lt;/code> (reverter) imediatamente sem tentar encontrar a causa raiz.&lt;/p>
&lt;hr>
&lt;h2 id="3-o-conceito-de-costuras-seams-para-criar-testabilidade">3. O Conceito de &amp;ldquo;Costuras (Seams)&amp;rdquo; para Criar Testabilidade
&lt;/h2>&lt;p>A primeira barreira enfrentada ao tentar adicionar testes ao código legado são as &amp;ldquo;dependências&amp;rdquo;. Conexões diretas a bancos de dados, comunicações de rede, acessos a sistemas de arquivos embutidos no código etc., quando fortemente acoplados, impossibilitam a escrita de testes unitários (Unit Tests).&lt;/p>
&lt;p>É aqui que o conceito de &amp;ldquo;Costura (Seam)&amp;rdquo; entra em jogo. Uma costura refere-se a um &amp;ldquo;lugar onde você pode alterar o comportamento do sistema sem editar o código propriamente dito&amp;rdquo;. Em C++, usamos principalmente as seguintes 3 costuras:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Costuras de Objetos (Object Seams)&lt;/strong>: Polimorfismo usando funções virtuais (Virtual Functions).&lt;/li>
&lt;li>&lt;strong>Costuras de Tempo de Compilação (Compile-time Seams)&lt;/strong>: Troca de Templates (Templates) ou inclusões (&lt;code>#include&lt;/code>).&lt;/li>
&lt;li>&lt;strong>Costuras de Tempo de Vinculação (Link-time Seams)&lt;/strong>: Troca das bibliotecas ou arquivos de objeto vinculados durante a compilação.&lt;/li>
&lt;/ol>
&lt;p>Aproveitando essas costuras, substituímos os módulos do ambiente de produção por objetos simulados (Mocks) para ambientes de teste, isolando as dependências.&lt;/p>
&lt;hr>
&lt;h2 id="4-quebrando-o-forte-acoplamento-injeção-de-dependência-dependency-injection">4. Quebrando o Forte Acoplamento: Injeção de Dependência (Dependency Injection)
&lt;/h2>&lt;p>A Injeção de Dependência (DI: Dependency Injection) é um padrão poderoso para separar a responsabilidade de criação de objetos do interior de uma classe para o exterior.&lt;/p>
&lt;p>Primeiro, vejamos um design de classe em C++ que é legado e fortemente acoplado.&lt;/p>
&lt;pre class="mermaid">
classDiagram
class LegacyOrderProcessor {
-DatabaseConnection* db
-FileLogger* logger
+LegacyOrderProcessor()
+processOrder(int orderId) void
}
class DatabaseConnection {
+DatabaseConnection()
+save(int orderId) void
}
class FileLogger {
+FileLogger()
+log(string msg) void
}
LegacyOrderProcessor --&amp;gt; DatabaseConnection : &amp;#34;Criação direta (usa new)&amp;#34;
LegacyOrderProcessor --&amp;gt; FileLogger : &amp;#34;Criação direta (usa new)&amp;#34;
&lt;/pre>
&lt;p>Este &lt;code>LegacyOrderProcessor&lt;/code> cria diretamente &lt;code>DatabaseConnection&lt;/code> e &lt;code>FileLogger&lt;/code> usando &lt;code>new&lt;/code> dentro de seu construtor, por isso não há costuras para substituí-los por mocks. Vamos refatorar isso para acoplamento fraco usando interfaces (classes puramente virtuais).&lt;/p>
&lt;pre class="mermaid">
classDiagram
class IDatabase {
&amp;lt;&amp;lt;interface&amp;gt;&amp;gt;
+save(int orderId) void
}
class ILogger {
&amp;lt;&amp;lt;interface&amp;gt;&amp;gt;
+log(string msg) void
}
class ModernOrderProcessor {
-std::unique_ptr~IDatabase~ db
-std::shared_ptr~ILogger~ logger
+ModernOrderProcessor(std::unique_ptr~IDatabase~ db, std::shared_ptr~ILogger~ logger)
+processOrder(int orderId) void
}
class DatabaseConnection {
+save(int orderId) void
}
class FileLogger {
+log(string msg) void
}
IDatabase &amp;lt;|.. DatabaseConnection : &amp;#34;Implementação&amp;#34;
ILogger &amp;lt;|.. FileLogger : &amp;#34;Implementação&amp;#34;
ModernOrderProcessor --&amp;gt; IDatabase : &amp;#34;DI (Injeção de construtor)&amp;#34;
ModernOrderProcessor --&amp;gt; ILogger : &amp;#34;DI (Injeção de construtor)&amp;#34;
&lt;/pre>
&lt;h3 id="exemplo-de-código-legado-c03">Exemplo de Código Legado (C++03)
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">LegacyOrderProcessor&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">private&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DatabaseConnection&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">db_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">FileLogger&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">logger_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LegacyOrderProcessor&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">db_&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">DatabaseConnection&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3306&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logger_&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">FileLogger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/var/log/app.log&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">~&lt;/span>&lt;span class="n">LegacyOrderProcessor&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">db_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">logger_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">processOrder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">orderId&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Processamento...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">db_&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">save&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">orderId&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logger_&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Order processed&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="após-a-refatoração-c-moderno">Após a Refatoração (C++ Moderno)
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Definição das interfaces (Costura de Objeto)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">IDatabase&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">virtual&lt;/span> &lt;span class="o">~&lt;/span>&lt;span class="n">IDatabase&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">default&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">virtual&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">save&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">orderId&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">ILogger&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">virtual&lt;/span> &lt;span class="o">~&lt;/span>&lt;span class="n">ILogger&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">default&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">virtual&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">msg&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Design onde as dependências são injetadas externamente
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">class&lt;/span> &lt;span class="nc">ModernOrderProcessor&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">private&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">IDatabase&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">db_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">shared_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ILogger&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">logger_&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Injeção de Construtor (Constructor Injection)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">ModernOrderProcessor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">IDatabase&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">db&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">shared_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">ILogger&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">logger&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">:&lt;/span> &lt;span class="n">db_&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">move&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">db&lt;/span>&lt;span class="p">)),&lt;/span> &lt;span class="n">logger_&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">move&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logger&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">processOrder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">orderId&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">db_&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">save&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">orderId&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logger_&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Order processed&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Melhorando o design desta forma, podemos criar facilmente objetos mock para &lt;code>IDatabase&lt;/code> usando frameworks como Google Mock (gmock), tornando possível o Desenvolvimento Orientado a Testes (TDD).&lt;/p>
&lt;hr>
&lt;h2 id="5-o-desmantelamento-das-terríveis-variáveis-globais-e-do-singleton">5. O Desmantelamento das Terríveis Variáveis Globais e do Singleton
&lt;/h2>&lt;p>O que causa mais dores de cabeça no C++ legado é o uso excessivo de variáveis globais e do &amp;ldquo;padrão Singleton (Singleton pattern)&amp;rdquo;. O Singleton pode parecer um padrão de design conveniente à primeira vista, mas, na realidade, não passa de uma &amp;ldquo;variável global disfarçada de orientação a objetos&amp;rdquo;.&lt;/p>
&lt;p>O estado global compartilha o estado entre os casos de teste, impossibilitando a execução de testes em paralelo e causando testes instáveis (Flaky Tests) de origem desconhecida.&lt;/p>
&lt;p>A solução é eliminar a dependência implícita do estado global e passar explicitamente os estados necessários como argumentos de função (parametrização). Isso é chamado de &amp;ldquo;passagem de contexto&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="6-a-modernização-do-gerenciamento-de-memória-e-a-essência-de-raii">6. A Modernização do Gerenciamento de Memória e a Essência de RAII
&lt;/h2>&lt;p>No código da era do C++98/03, &lt;code>new&lt;/code> e &lt;code>delete&lt;/code> estão espalhados por toda a base de código, servindo como um terreno fértil para vazamentos de memória (memory leaks) e ponteiros pendentes (dangling pointers). No C++ Moderno (C++11 e posterior), o conceito de &lt;strong>Propriedade (Ownership)&lt;/strong> é suportado em nível de linguagem, e o gerenciamento seguro de recursos usando ponteiros inteligentes tornou-se o padrão.&lt;/p>
&lt;h3 id="raii-resource-acquisition-is-initialization">RAII (Resource Acquisition Is Initialization)
&lt;/h3>&lt;p>RAII é o idioma mais importante do C++. Ao associar a aquisição de recursos com a inicialização do objeto (construtor) e a liberação de recursos com a destruição do objeto (destrutor), garantimos que os recursos sejam invariavelmente liberados ao sair do escopo.&lt;/p>
&lt;p>Mesmo se ocorrerem exceções (Exceptions), o destrutor das variáveis locais é chamado automaticamente durante o processo de desenrolar da pilha (Stack Unwinding), impedindo assim vazamentos de recursos.&lt;/p>
&lt;p>&lt;strong>Antes (Código legado perigoso)&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">processFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="kt">char&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">filename&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">FILE&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">file&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fopen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filename&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;r&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Data&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">Data&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">readData&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Fácil de esquecer
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">fclose&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Fácil de esquecer
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">process&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(...)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Evitar memory leak na exceção
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">fclose&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">throw&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fclose&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Neste código, os recursos devem ser liberados manualmente em cada ramificação do fluxo de controle, resultando em uma estrutura extremamente frágil.&lt;/p>
&lt;p>&lt;strong>Depois (Utilização de RAII e Ponteiros Inteligentes)&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">processFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">filename&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// std::ifstream gerencia o handle do arquivo usando RAII
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">ifstream&lt;/span> &lt;span class="n">file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filename&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">is_open&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// std::unique_ptr é o proprietário exclusivo que gerencia a memória heap com RAII
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">auto&lt;/span> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_unique&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Data&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">readData&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Liberado automaticamente ao sair do escopo
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Mesmo se ocorrer uma exceção, os destrutores do unique_ptr e do ifstream
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// garantem que os recursos sejam liberados de forma segura (garantia de zero memory leaks)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">process&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Através desta refatoração, a quantidade de código é drasticamente reduzida, a intenção torna-se clara e, acima de tudo, a segurança de exceção (Exception Safety) é perfeitamente garantida.&lt;/p>
&lt;hr>
&lt;h2 id="7-o-aumento-da-expressividade-com-os-recursos-do-c-moderno">7. O Aumento da Expressividade com os Recursos do C++ Moderno
&lt;/h2>&lt;p>Na refatoração de código legado, devemos tirar o máximo proveito dos benefícios das atualizações das funcionalidades da linguagem.&lt;/p>
&lt;h3 id="71-inferência-de-tipos-com-auto">7.1. Inferência de Tipos com &lt;code>auto&lt;/code>
&lt;/h3>&lt;p>A legibilidade é melhorada ao substituir declarações redundantes, como nomes de tipos longos de iteradores, por &lt;code>auto&lt;/code>. No entanto, a melhor prática é não transformar tudo em &lt;code>auto&lt;/code>, mas limitá-lo a casos em que &amp;ldquo;o tipo é óbvio ao observar o lado direito&amp;rdquo;.&lt;/p>
&lt;h3 id="72-cálculos-em-tempo-de-compilação-com-constexpr-e-consteval">7.2. Cálculos em Tempo de Compilação com &lt;code>constexpr&lt;/code> e &lt;code>consteval&lt;/code>
&lt;/h3>&lt;p>Usamos proativamente &lt;code>constexpr&lt;/code> para reduzir a sobrecarga no tempo de execução e detectar erros em tempo de compilação.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Código legado (macros e cálculos em tempo de execução)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#define MAX_BUFFER_SIZE 1024
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">PI&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">3.1415926535&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">double&lt;/span> &lt;span class="nf">calculateCircleArea&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">double&lt;/span> &lt;span class="n">radius&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">PI&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">radius&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">radius&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Estilo C++ Moderno (C++20 em diante)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">constexpr&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">size_t&lt;/span> &lt;span class="n">MaxBufferSize&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1024&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">constexpr&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">Pi&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mf">3.14159265358979323846&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// consteval garante que a função possa ser avaliada em tempo de compilação (C++20)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">consteval&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="nf">calculateCircleArea&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">double&lt;/span> &lt;span class="n">radius&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Pi&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">radius&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">radius&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Custo em tempo de execução nulo. A constante resultante é incorporada diretamente no binário durante a compilação.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">constexpr&lt;/span> &lt;span class="kt">double&lt;/span> &lt;span class="n">area&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">calculateCircleArea&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">10.0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="73-atributo-nodiscard">7.3. Atributo &lt;code>[[nodiscard]]&lt;/code>
&lt;/h3>&lt;p>Para evitar bugs nos quais os valores de retorno das funções (especialmente códigos de erro e estados importantes) são ignorados, aplicamos o atributo &lt;code>[[nodiscard]]&lt;/code>. Com isso, o compilador emitirá um aviso para chamadas de função onde o valor de retorno não é recebido.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[[nodiscard]]&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">initializeSystem&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="c1">// Proibir que o valor de retorno seja ignorado
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="8-utilização-de-ferramentas-de-automação-e-melhoria-contínua">8. Utilização de Ferramentas de Automação e Melhoria Contínua
&lt;/h2>&lt;p>Modificar uma grande base de código legado manualmente não é realista. Aproveitar o poder de cadeias de ferramentas (toolchains) é o caminho mais rápido para o sucesso.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Clang-Tidy&lt;/strong>: Um poderoso linter e ferramenta de análise estática para C++. Ao habilitar as verificações do tipo &lt;code>modernize-*&lt;/code>, ele pode aplicar automaticamente (Fix-it) a utilização de &lt;code>auto&lt;/code>, substituições por &lt;code>nullptr&lt;/code>, adições de &lt;code>override&lt;/code>, entre outras coisas.&lt;/li>
&lt;li>&lt;strong>AddressSanitizer (ASan)&lt;/strong>: Ao incluí-lo como uma opção de compilação (&lt;code>-fsanitize=address&lt;/code>), ele identifica com precisão os vazamentos de memória e os buffer overruns (estouros de buffer) durante a execução. Ele deve estar sempre habilitado ao executar testes.&lt;/li>
&lt;li>&lt;strong>Construção de Pipelines CI/CD&lt;/strong>: Usando GitHub Actions ou GitLab CI, executamos builds, testes automáticos e análise estática para todos os Pull Requests (solicitações de pull), evitando assim a introdução de novas dívidas técnicas.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="9-conclusão">9. Conclusão
&lt;/h2>&lt;p>A refatoração de um código C++ legado não é algo que se conclua da noite para o dia. É um trabalho delicado e arrojado, semelhante a realizar uma cirurgia em um sistema.&lt;/p>
&lt;p>Lembre-se dos seguintes passos discutidos neste artigo:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Medir a complexidade e construir uma estratégia com base em fatos&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Descobrir as costuras e proteger o sistema com testes de caracterização&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Quebrar o forte acoplamento usando DI e erradicar os estados globais&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Remover a ansiedade do gerenciamento de memória usando RAII e ponteiros inteligentes&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Fazer uso das funcionalidades do C++ Moderno e deixar o compilador trabalhar para você&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>A verdadeira essência da refatoração é manter o espírito da &amp;ldquo;Regra do Escoteiro (deixe o acampamento mais limpo do que o encontrou)&amp;rdquo; e continuar melhorando o código, pouco a pouco, mas de maneira constante, durante suas tarefas de desenvolvimento diárias.&lt;/p></description></item></channel></rss>