Revisão de código em C++: no que os seniors pegam primeiro

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que sua revisão está se transformando em um campo de batalha?

\n\n

Você enviou um Merge Request. Parece tudo limpo, a lógica correta, o código compila. Uma hora depois, chega a resposta do senior: "-10 pontos para a Grifinória" e 35 comentários em 200 linhas de código. Familiar?

\n\n

A revisão de código em C++ não é apenas uma verificação de sintaxe. É uma arte que separa juniors de seniors. C++ dá ao desenvolvedor um enorme poder sobre a memória e o desempenho, mas com grandes poderes vêm grandes responsabilidades por comportamento indefinido e vazamentos de recursos.

\n\n

Neste artigo, vamos entrar na mente de um revisor experiente. Reuni comentários reais que seniors deixam em code reviews em projetos de produção. Se você programa em C++ e quer que seus PRs sejam aprovados na primeira tentativa — leia com atenção. E se você é tech lead — use esta checklist para integrar novatos.

\n\n

1. Tiro no pé: gerenciamento manual de memória

\n\n

A polêmica mais comum em revisões é "por que você não está usando ponteiros inteligentes?". Seniors odeiam new e delete puros em C++ moderno (C++11 e posteriores).

\n\n

Exemplo ruim

\n
class DataProcessor {\n    int* buffer;\n    size_t size;\npublic:\n    DataProcessor(size_t s) : size(s) {\n        buffer = new int[s]; // Quem vai deletar?\n    }\n\n    ~DataProcessor() {\n        delete[] buffer; // E se houver uma exceção no construtor?\n    }\n};
\n\n

Comentário do senior: "Violação de RAII. Se o construtor lançar uma exceção após a alocação de memória — o destrutor não será chamado. Vazamento de memória. Use std::vector ou std::unique_ptr."

\n\n

Exemplo correto

\n
class DataProcessor {\n    std::vector<int> buffer;\npublic:\n    explicit DataProcessor(size_t s) : buffer(s) {}\n};
\n\n

Seniors adoram RAII (Resource Acquisition Is Initialization). Se você escreve new no código, esteja preparado para explicar por que std::make_unique ou std::vector não são adequados. Em 95% dos casos, eles são.

\n\n

2. Const-correctness: coloque sua "vírgula"

\n\n

Um const faltando é uma bandeira vermelha para qualquer desenvolvedor senior em C++. Não é apenas estilo, é um contrato com o leitor do código e com o compilador.

\n\n

O que irrita na revisão

\n
std::string getName() { // Por que não const?\n    return name;\n}\n\nvoid printData(std::vector<int>& data) { // Cópia? Referência? Modifica?\n    for (auto& item : data) {\n        std::cout << item;\n    }\n}
\n\n

Comentário do senior: "O método getName() não modifica o objeto — torne-o const. O parâmetro data não é modificado — passe const std::vector<int>&. Caso contrário, o código chamador não sabe se você vai modificar os dados dele ou não."

\n\n

Corrigindo

\n
std::string getName() const { // método const\n    return name;\n}\n\nvoid printData(const std::vector<int>& data) { // referência const\n    for (const auto& item : data) {\n        std::cout << item;\n    }\n}
\n\n

A regra é simples: se o método não altera o estado do objeto — const. Se a função não altera o argumento — const T&. Const correctness em C++ não é uma opção, é um padrão.

\n\n

3. Move semantics: copiar não é a nossa religião

\n\n

C++ moderno é sobre mover, não copiar. Seniors percebem imediatamente onde você cria cópias desnecessárias e prejudica o desempenho.

\n\n

Padrão ruim

\n
std::vector<int> processData(std::vector<int> data) { // Cópia na entrada\n    // ... muita lógica ...\n    return data; // Cópia na saída? Ou NRVO?\n}\n\nvoid caller() {\n    std::vector<int> bigData = {1, 2, 3, ... 1000000};\n    auto result = processData(bigData); // Mais uma cópia!\n}
\n\n

Coment

Blogs

Book Recommendations