Code review em C++: o que verificar e como dar feedback na prática
\n\nCode review não é apenas uma formalidade, mas uma ferramenta poderosa para melhorar a qualidade do código. Em C++, a revisão é especialmente importante devido à complexidade da linguagem: gerenciamento manual de memória, templates, herança múltipla. Neste artigo, vamos analisar o que observar ao revisar código C++ e como formular observações para que sejam úteis, e não ofensivas.
\n\n1. Segurança de memória e RAII
\n\nA primeira coisa a verificar é o gerenciamento de recursos. Em C++ não há coletor de lixo, portanto vazamentos de memória e dupla liberação são problemas comuns. O padrão chave é RAII (Resource Acquisition Is Initialization).
\n\nO que verificar:
\n- \n
- Ponteiros inteligentes (
std::unique_ptr,std::shared_ptr) estão sendo usados em vez denew/deletepuros? \n - Há chamadas manuais de
deleteno código? (Exceto em casos raros de trabalho de baixo nível) \n - As classes RAII estão implementadas corretamente: o recurso é adquirido no construtor e liberado no destrutor? \n
- O destrutor virtual foi esquecido na classe base? \n
// ❌ Ruim: gerenciamento manual\nvoid process() {\n int* data = new int[100];\n // ... se houver uma exceção, a memória vazará\n delete[] data;\n}\n\n// ✅ Bom: RAII via std::vector\nvoid process() {\n std::vector<int> data(100);\n // seguro contra exceções\n}\n\nComo dar feedback: Em vez de "Você esqueceu de liberar a memória", diga: "Aqui é melhor usar std::vector ou std::unique_ptr — isso liberará os recursos automaticamente e tornará o código à prova de exceções".
2. Const-correctness e referências
\n\nC++ permite indicar explicitamente que os dados não devem ser alterados. Isso melhora a legibilidade e permite que o compilador otimize melhor o código.
\n\nO que verificar:
\n- \n
- Todos os parâmetros que não são modificados estão marcados como
const? \n - Objetos grandes estão sendo passados por referência constante (
const T&), e não por valor? \n - Métodos que não modificam o objeto estão marcados como
const? \n const_castnão está sendo usado sem extrema necessidade? \n
// ❌ Ruim: cópia de objeto grande\nstd::string toUpper(std::string s); // cópia\n\n// ✅ Bom: referência constante\nstd::string toUpper(const std::string& s); // sem cópia\n\n// ❌ Ruim: método não é const, embora não altere o estado\nclass Point {\n int x, y;\npublic:\n int getX() { return x; } // deveria ser const\n};\n\n// ✅ Bom\nint getX() const { return x; }\n\nComo dar feedback: "Vamos adicionar const para os parâmetros que não são modificados — isso tornará a interface mais clara e evitará alterações acidentais".
\n\n3. Uso de STL e algoritmos
\n\nA biblioteca padrão do C++ contém muitas soluções prontas. Reinventar a roda é um erro comum de iniciantes.
\n\nO que verificar:
\n- \n
- Existem loops manuais que poderiam ser substituídos por algoritmos (
std::find,std::sort,std::transform)? \n - O contêiner foi escolhido corretamente? (
std::vectorpara acesso aleatório,std::listpara inserções frequentes no meio) \n std::string_viewestá sendo usado para passar strings sem cópia? \n reserve()parastd::vectorfoi esquecido quando o tamanho é conhecido? \n
// ❌ Ruim: busca manual\nbool contains(const std::vector<int>& v, int val) {\n for (size_t i = 0; i < v.size(); ++i) {\n if (v[i] == val) return true;\n }\n return false;\n}\n\n// ✅ Bom: uso de STL\nbool contains(c