struct vs class en C++: la única diferencia real

Respuesta corta: son la misma cosa con un valor por defecto invertido: los miembros de un struct son públicos por defecto; los de una class, privados. Lo mismo pasa con la herencia. Todo lo demás — métodos, constructores, herencia, plantillas — funciona igual en ambos.

Aviso: nuestro motor en el navegador cubre el núcleo didáctico y todavía no soporta struct/class definidos por el usuario, así que estos fragmentos son para tu compilador de escritorio. Los conceptos son material central de entrevista, así que sigue leyendo.

Prueba: una palabra clave cambia el acceso

struct PointS {
    int x;      // público  (valor por defecto de struct)
    int y;
};

class PointC {
    int x;      // privado (valor por defecto de class)
    int y;
};

int main() {
    PointS s;
    s.x = 1;    // vale — x es público

    PointC c;
    c.x = 1;    // ERROR: 'int PointC::x' es privado
}

Esa es toda la diferencia mecánica. Cambia class por struct en el ejemplo y el error desaparece. Nada más distingue a las dos palabras clave.

Ambos pueden hacer de todo

// Un struct con métodos, constructor y miembros privados: perfectamente legal
struct CuentaBancaria {
  private:
    double saldo = 0;
  public:
    explicit CuentaBancaria(double inicial) : saldo(inicial) {}
    void ingresar(double cantidad) {
        if (cantidad > 0) saldo += cantidad;
    }
    double getSaldo() const { return saldo; }
};

// Una class usada como simple paquete de datos: también legal, solo que raro
class Config {
  public:
    int ancho;
    int alto;
};

Entonces, si son intercambiables, ¿por qué existen las dos? Historia y convención. C++ heredó struct de C (donde solo puede contener datos) y añadió class para la programación orientada a objetos — y después las convirtió en la misma construcción con valores por defecto distintos.

La convención que siguen los proyectos reales

La prueba del olor: ¿alguna asignación arbitraria de sus miembros públicos produciría un objeto sin sentido? Sí → class. No → struct.

El segundo valor por defecto que todos olvidan: la herencia

struct DerivadaS : Base { };   // hereda de forma PUBLICA por defecto
class  DerivadaC : Base { };   // hereda de forma PRIVADA por defecto

Misma palabra clave, mismo valor por defecto invertido — pero para la herencia en vez de para los miembros. En la práctica conviene escribir siempre el nivel de acceso de forma explícita al heredar, pero a los entrevistadores les encanta este detalle.

Preguntas de entrevista sobre este tema

  1. «¿Qué diferencia hay entre struct y class en C++?» — el acceso por defecto a los miembros y el tipo de herencia por defecto; nada más. (En C la respuesta es otra historia: un struct no puede tener métodos.)
  2. «¿Es struct más rápido que class?» — no. Código idéntico, rendimiento idéntico; solo cambia el acceso por defecto.
  3. «¿Cuándo elegirías struct a propósito?» — agregados pasivos (puntos, colores, DTO) y contextos de interoperabilidad donde importa un diseño compatible con C.
  4. «¿Qué es un agregado?» — a grandes rasgos: un struct sin constructores de usuario ni miembros privados, inicializable con llaves: Point p {1, 2};. Una clase con invariantes no puede ser agregado, y eso es deliberado.
  5. «¿Para qué hacer privados los miembros?» — para que el objeto pueda garantizar sus propias reglas (invariantes); con datos públicos cualquiera puede romperlas y nunca podrás añadir validación sin romper a todos los que llaman.

Practica en tu compilador de escritorio

  1. Escribe la prueba PointS/PointC de arriba y lee el error exacto del compilador para c.x = 1.
  2. Cambia PointC a struct y confirma que el error desaparece — mismo código, una palabra.
  3. Escribe class Temperatura con un celsius privado y un set(double) que rechace valores por debajo de −273,15 — eso es una invariante, justo lo que un struct con datos públicos no puede proteger.

Relacionado: pasar por valor, puntero o referencia (cómo viajan estos objetos a las funciones), stack vs heap (dónde viven), 15 preguntas de entrevista para juniors (esta es la 14).