✅ Objetivo: Aprender sobre sobrecarga de operadores, herencia simple y gestión segura de recursos ✅ Nivel: Intermedio ✅ Temas clave:
operator overload,inheritance,copy constructor,destructor,assign operator
- Sobrecarga de Operadores
- Herencia Simple
- Regla de los Tres
- Constructores con Lista de Inicialización
- Punteros y Copias Profundas
- Errores Comunes
- Buenas Prácticas
📘 ¿Qué es?
C++ permite redefinir el comportamiento de operadores (+, =, <<, etc.) para tus propias clases.
class Punto {
private:
int x, y;
public:
Punto(int x, int y) : x(x), y(y) {}
Punto operator+(const Punto& other) const {
return Punto(x + other.x, y + other.y);
}
void mostrar() const {
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
};🧪 Uso:
Punto a(1, 2), b(3, 4);
Punto c = a + b;
c.mostrar(); // (4, 6)📘 ¿Qué es? Una clase puede heredar atributos y métodos de otra clase base.
class Animal {
public:
void habla() const {
std::cout << "Hace un sonido" << std::endl;
}
};
class Perro : public Animal {
public:
void ladra() const {
std::cout << "Guau!" << std::endl;
}
};🧪 Uso:
Perro p;
p.habla(); // heredado de Animal
p.ladra(); // definido en Perro🎯 Siempre usa public inheritance para mantener accesibilidad.
📘 ¿Qué es? Si una clase gestiona recursos (como memoria dinámica), debes implementar los tres:
| Método | Uso |
|---|---|
| Destructor | Libera recursos |
| Constructor por copia | Copia recursos |
Operador = |
Duplica recursos con seguridad |
class Texto {
private:
char* contenido;
public:
Texto(const char* str) {
contenido = new char[strlen(str) + 1];
strcpy(contenido, str);
}
~Texto() {
delete[] contenido;
}
Texto(const Texto& other) {
contenido = new char[strlen(other.contenido) + 1];
strcpy(contenido, other.contenido);
}
Texto& operator=(const Texto& other) {
if (this != &other) {
delete[] contenido;
contenido = new char[strlen(other.contenido) + 1];
strcpy(contenido, other.contenido);
}
return *this;
}
};📘 ¿Qué es? Una forma eficiente de inicializar atributos, especialmente constantes y referencias.
class Recta {
private:
const int m;
int b;
public:
Recta(int pendiente, int interseccion) : m(pendiente), b(interseccion) {}
};🎯 Obligatorio para inicializar miembros const o referencias (&).
📘 ¿Por qué importa? Si tu clase tiene punteros, debes implementar copia profunda para evitar bugs.
class Imagen {
private:
int* pixeles;
public:
Imagen() {
pixeles = new int[1000];
}
~Imagen() {
delete[] pixeles;
}
Imagen(const Imagen& other) {
pixeles = new int[1000];
std::copy(other.pixeles, other.pixeles + 1000, pixeles);
}
Imagen& operator=(const Imagen& other) {
if (this != &other) {
delete[] pixeles;
pixeles = new int[1000];
std::copy(other.pixeles, other.pixeles + 1000, pixeles);
}
return *this;
}
};🔍 Sin copia profunda, dos objetos compartirían memoria → bugs difíciles.
❌ Olvidar liberar memoria en el destructor
❌ Usar = sin sobrecargar cuando se necesita
❌ No implementar constructor por copia en clases con punteros
❌ No verificar this != &other en operador de asignación
❌ Herencia sin virtual destructor (ver módulo 03)
✅ Implementa la Regla de los Tres si tu clase usa new
✅ Usa listas de inicialización siempre que sea posible
✅ Verifica autoasignación en operator=
✅ Prefiere std::string y std::vector en lugar de punteros raw (cuando sea posible)
✅ Testea tus clases con copias, asignaciones, destrucciones
Este proyecto está bajo la licencia MIT. ⚖️📄🆓