---
description: Refactoriza una clase C++ aplicando buenas prácticas de estilo
---

# Refactor Class Command

Refactoriza una clase C++ siguiendo estas reglas de estilo y buenas prácticas:

## Reglas de Refactorización

### 1. Inicialización de Variables Miembro
- **Inicializar en la declaración** todas las variables "simples" que no tengan dependencias complejas:
  - Tipos primitivos: `int`, `float`, `bool`, etc.
  - Enumeraciones: valores de enum class
  - Valores por defecto conocidos: `0`, `0.0F`, `false`, `nullptr`, etc.
- **NO inicializar en declaración** si:
  - Dependen de otros miembros
  - Requieren llamadas a funciones complejas
  - Son punteros a recursos que necesitan construcción específica

### 2. Structs con Valores por Defecto
- **Todos los miembros de structs** deben tener valores por defecto:
  - Tipos primitivos: `int x{0}`, `float y{0.0F}`, `bool flag{false}`
  - Strings: `std::string name{}`
  - Punteros: `Type* ptr{nullptr}`
- **Ventajas**: Inicialización segura, evita valores indefinidos

### 3. Arrays C-style → std::array
- Convertir **todos** los arrays C-style a `std::array`:
  - `Type array[N]` → `std::array<Type, N> array{}`
  - Inicializar con `{}` para zero-initialization
- Agregar `#include <array>` si no existe
- **Ventajas**: type-safety, size(), métodos STL, sin decay a pointer

### 3. Reorganización de la Clase

#### Orden de Secciones
1. **public** (primero)
2. **private** (después)

#### Dentro de cada sección (private principalmente)
1. **Estructuras y enumeraciones** (tipos anidados)
2. **Constantes** (static constexpr)
3. **Métodos** (funciones miembro)
4. **Variables miembro** (al final)

### 4. Agrupación y Comentarios de Métodos
- **En sección public**: Agrupar métodos relacionados funcionalmente
- **Comentarios en línea** (a la derecha) para describir cada método/grupo
- **Formato**: `void method();  // Descripción concisa`
- **Espaciado**: Línea en blanco entre grupos funcionales

**Ejemplo:**
```cpp
public:
    static void init(...);    // Inicialización singleton
    static void destroy();    // Destrucción singleton
    static auto get() -> T*;  // Acceso al singleton

    void render();            // Renderizado
    void update(float dt);    // Actualización lógica

    auto isActive() -> bool;  // Consulta estado
```

### 5. Comentarios de Variables
- **Posición**: A la derecha de la variable/grupo
- **Formato**: `// Descripción concisa`
- Agrupar variables relacionadas con un comentario común

### 6. Constructores en Structs
- **Eliminar constructores por defecto redundantes** en structs:
  - Si todos los miembros tienen inicialización en declaración
  - Y no hay múltiples constructores
  - Eliminar `explicit Type() = default;`
- El compilador generará automáticamente un constructor por defecto

**Ejemplo:**
```cpp
struct Data {
    int x{0};
    std::string name{};
    // NO NECESITA: explicit Data() = default;
};
```

### 7. Includes Necesarios
- Agregar includes faltantes según lo que se use
- Mantener orden alfabético si es posible

### 8. Header Guards
- **Usar `#pragma once`** en todas las cabeceras (`.hpp`)
- **NO usar** `#ifndef`/`#define`/`#endif` tradicionales
- `#pragma once` debe ser la primera línea del archivo (antes de includes)
- **Ventajas**: Más simple, menos propenso a errores, ampliamente soportado

## Ejemplo de Aplicación

### Antes:
```cpp
class Example {
    private:
        struct Data {
            std::string name;
            int value;
        };

        int counter_;
        bool flag_;
        float values_[10];

    public:
        Example();
        void update();
};

// Constructor
Example::Example()
    : counter_(0),
      flag_(false) {
    for (int i = 0; i < 10; ++i) {
        values_[i] = 0.0F;
    }
}
```

### Después:
```cpp
#pragma once

#include <array>

class Example {
    public:
        Example() = default;  // Ya no necesita inicializar
        void update();

    private:
        // Tipos anidados
        struct Data {
            std::string name{};    // Nombre con valor por defecto
            int value{0};          // Valor inicializado
        };

        // Variables miembro
        int counter_{0};                        // Contador de frames
        bool flag_{false};                      // Estado activo
        std::array<float, 10> values_{};        // Buffer de valores
};
```

## Tareas a Realizar

Cuando uses este comando en una clase específica:

1. **Leer** el archivo `.hpp` y `.cpp` correspondiente
2. **Verificar** que la cabecera use `#pragma once` (reemplazar `#ifndef`/`#define`/`#endif` si existen)
3. **Identificar** structs y agregar valores por defecto a todos sus miembros
4. **Identificar** variables que pueden inicializarse en declaración
5. **Identificar** arrays C-style que convertir a std::array
6. **Reorganizar** la estructura de la clase (public/private, agrupación)
7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes
8. **Compilar** para verificar sintaxis correcta
9. **Ejecutar clang-tidy** (análisis, sin --fix) y revisar resultados
10. **Ejecutar cppcheck** (nivel -w) y revisar resultados
11. **Aplicar fixes apropiados** basados en análisis de linters
12. **Recompilar** si se aplicaron fixes
13. **Reportar resumen** al usuario: cambios + hallazgos de linters

## Workflow de Linters (Pasos 9-12)

### Paso 9: Ejecutar clang-tidy

```bash
tools/linter/run_clang-tidy.sh archivo.cpp archivo.hpp
```

**Analizar resultados:**
- Identificar issues críticos (bugprone, cert)
- Separar recomendaciones válidas de falsos positivos
- Ignorar: magic-numbers en game constants, defaults.hpp errors
- Si hay issues críticos, informar al usuario y pausar
- Si solo hay recomendaciones, continuar

### Paso 10: Ejecutar cppcheck

```bash
tools/linter/run_cppcheck.sh -w --path archivo.cpp
```

**Leer archivo de resultados:**
- `tools/linter/cppcheck-result-warning-style-performance.txt`
- Identificar errores críticos (error, nullPointer, uninitvar)
- Separar warnings de style issues
- Filtrar falsos positivos (passedByValue para tipos pequeños, unusedFunction en API pública)
- Si hay errores críticos, informar al usuario y pausar

### Paso 11: Aplicar Fixes

**Si hay issues aplicables:**

1. **Fixes automáticos de clang-tidy** (solo si son seguros):
   - modernize-use-auto
   - readability-redundant-access-specifiers
   - Performance optimizations claras

   ```bash
   tools/linter/run_clang-tidy.sh --fix archivo.cpp archivo.hpp
   ```

2. **Fixes manuales necesarios:**
   - Inicializar variables no inicializadas
   - Corregir null pointer issues
   - Resolver memory leaks

3. **Documentar cambios** para el reporte final

### Paso 12: Recompilar

Si se aplicaron fixes en paso 11:

```bash
cmake --build build
```

**Verificar:**
- ✅ Compilación exitosa → Continuar a reporte
- ❌ Errores → Informar al usuario, sugerir revisión manual

## Formato de Reporte Final (Paso 13)

```
=== Refactor Completado: ClassName ===

📝 Cambios estructurales:
  ✅ #pragma once aplicado
  ✅ 3 structs actualizados con valores por defecto
  ✅ 12 variables movidas a inicialización en declaración
  ✅ 2 arrays C-style → std::array
  ✅ Clase reorganizada (public primero, variables al final)
  ✅ Constructor simplificado (elimina 12 inicializaciones redundantes)

🔍 Análisis de linters:

clang-tidy:
  ✅ Sin issues críticos
  🟡 3 recomendaciones aplicadas automáticamente:
     - Modernize: use auto (2 lugares)
     - Readability: redundant specifier (1 lugar)
  ⚪ 2 opcionales ignorados:
     - magic-numbers en game constants

cppcheck:
  ✅ Sin errores
  🟡 2 style issues encontrados:
     - Unused variable 'temp' en línea 45 → Eliminada
     - Redundant assignment en línea 102 → Corregida

📊 Resultado:
  ✅ Compilación exitosa
  ✅ Todos los linters pasan sin issues críticos
  ✅ Código refactorizado y verificado

💡 Próximos pasos:
  - Revisar cambios manualmente
  - Ejecutar tests si existen
  - Commitear con mensaje descriptivo
```

## Notas Importantes

- **No cambiar lógica**: Solo refactorización estructural
- **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso
- **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado)
- **Validar compilación**: Siempre verificar que compile después de cambios
- **Linters integrados**: Análisis automático post-refactor para garantizar calidad
- **Fixes inteligentes**: Solo aplicar --fix de clang-tidy si los cambios son seguros
- **Contexto importa**: Game code tiene patrones legítimos (magic numbers, etc.)
- **Falsos positivos**: Identificar y documentar, no corregir ciegamente
