Conceptos Avanzados de Clases y Objetos en C++

Constructores Adicionales

Asignación en el Cuerpo del Constructor

Las sentencias dentro del cuerpo de un constructor realizan asignaciones, no inicializaciones. La inicialización ocurre solo una vez, mientras que el cuerpo permite múltiples asignaciones:

class Fecha {
    int _anio;
    int _mes;
    int _dia;
public:
    Fecha(int anio = 2003, int mes = 12, int dia = 12) {
        _anio = anio;
        _mes = mes;
        _dia = dia;  // Asignación, no inicialización
    }
};

Lista de Inicialización

Es el lugar donde los miembros se definen e inicializan. Cada variable miembro debe aparecer una sola vez:

class Fecha {
    int _anio;
    int _mes;
    int _dia;
public:
    Fecha(int anio = 2003, int mes = 12, int dia = 12)
        : _anio(anio), _mes(mes), _dia(dia) {}
};

Casos obligatorois para lista de inicialización:

  • Miembros const o referencias
  • Tipos personalizados sin constructor por defecto
class Hora {
    int _hora;
    int _minuto;
public:
    Hora(int h, int m) : _hora(h), _minuto(m) {}
};

class Evento {
    const int _id;
    Hora _hora;
public:
    Evento(int id, int h, int m) : _id(id), _hora(h, m) {}
};

Detalles de Constructores

Valores predeterminados en declaraciones:

class Sensor {
    int _valor = 0;
    int _precision = 1;
};

Palabra Clave explicit

Evita conversiones implícitas en constructores de un parámetro:

class Intervalo {
    int _minutos;
public:
    explicit Intervalo(int mins) : _minutos(mins) {}
};

void prueba() {
    Intervalo i1(30);     // Correcto
    Intervalo i2 = 30;    // Error: conversión implícita deshabilitada
}

Miembros static

Concepto

Variables compartidas por todas las instancias de la clase:

class Contador {
    static int instancias;
public:
    Contador() { instancias++; }
    static int obtener() { return instancias; }
};

int Contador::instancias = 0;

Características

  • Definición externa obligatoria
  • Acceso mediante nombre de clase u objeto
  • Funciones estáticas carecen de puntero this
int main() {
    Contador c1, c2;
    cout << Contador::obtener();  // 2
    cout << c1.obtener();        // 2
}

Relaciones de Amistad

Funciones Amigas

Acceden a miembros privados sin ser métodos:

class Almacen {
    int _capacidad;
    friend void verCapacidad(const Almacen& a);
};

void verCapacidad(const Almacen& a) {
    cout << a._capacidad;
}

Clases Amigas

Acceso bidireccional controlado:

class Motor {
    int rpm;
    friend class Coche;
};

class Coche {
    Motor m;
public:
    void ajustarRPM(int v) { m.rpm = v; }
};

Clases Internas

Clases anidadas con acceso privilegiado:

class Sistema {
    static int recursos;
    class Subsistema {
    public:
        void usar() { cout << recursos; }
    };
};

int Sistema::recursos = 100;

Características:

  • Acceso directo a miembros estáticos del exterior
  • Sin impacto en tamaño de clase contenedora

Objetos Anónimos

Objetos temporales sin identificador:

class Temporal {
public:
    ~Temporal() { cout << "Destruido"; }
};

int main() {
    Temporal();  // Objeto anónimo, destruido inmediatamente
}

Optimizaciones del Compilador

Ejemplo de elisión de copias:

class Ejemplo {
public:
    Ejemplo() = default;
    Ejemplo(const Ejemplo&) { cout << "Copia"; }
};

Ejemplo crear() {
    return Ejemplo();  // Omite copia
}

int main() {
    Ejemplo e = crear();  // Construcción directa
}

Etiquetas: C++ Constructores Lista de Inicialización explicit static

Publicado el 6-24 17:43