Files
jdd_opendingux/.claude/commands/refactor-class.md
2025-11-11 12:35:21 +01:00

5.3 KiB

description
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:

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:

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:

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:

#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. Verificar que compile correctamente
  9. Informar al usuario de los cambios realizados

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