Programacion orientada a objetos (POO) en C++¶
Objetivo¶
Tener una base clara de POO para despues entender mejor:
- diseño de clases en C++,
- como se traducen a bajo nivel,
- y como reconocer esos patrones en reversing.
Que es un objeto¶
Un objeto es una entidad con:
- estado (atributos/datos),
- comportamiento (metodos).
Ejemplo: Perro
- estado: nombre, peso, edad, esCachorro
- comportamiento: ladrar(), comer(), mostrarInfo()
En C++, una clase define ese tipo y un objeto es una instancia concreta.
Clase vs objeto¶
class Animal {
public:
std::string nombre;
float peso;
void sonar() const {
std::cout << "Sonido generico\n";
}
};
int main() {
Animal perro; // objeto
Animal gato; // otro objeto
}
Animales el tipo.perroygatoson objetos distintos de ese tipo.
Encapsulacion¶
La encapsulacion protege los datos internos y controla su acceso.
Regla practica:
- atributos:
privateoprotected, - interfaz publica: metodos
public.
class Animal {
private:
std::string nombre;
float peso;
public:
Animal(const std::string& n, float p) : nombre(n), peso(p) {}
std::string getNombre() const { return nombre; }
float getPeso() const { return peso; }
void setPeso(float p) {
if (p >= 0.0f) peso = p; // validacion minima
}
};
Constructores¶
Sirven para inicializar objetos en una sola linea:
Punto tecnico importante¶
En C++, los constructores no se sobreescriben y no participan en polimorfismo. En herencia, la clase derivada llama al constructor base por lista de inicializacion:
class Perro : public Animal {
private:
bool cachorro;
public:
Perro(const std::string& n, float p, bool c)
: Animal(n, p), cachorro(c) {}
};
Herencia¶
Permite reutilizar lo comun en una clase base y especializar en clases derivadas.
class Animal {
protected:
std::string nombre;
public:
Animal(const std::string& n) : nombre(n) {}
};
class Gato : public Animal {
public:
Gato(const std::string& n) : Animal(n) {}
};
Modificadores y herencia (resumen)¶
- herencia
public: mantiene visibilidad publica/protegida del padre. - herencia
protected: miembros publicos del padre pasan a protegidos. - herencia
private: miembros publicos/protegidos del padre pasan a privados.
private del padre nunca es accesible directo desde la hija.
Polimorfismo¶
Un mismo mensaje (metodo) produce comportamiento distinto segun el tipo real del objeto.
Se logra con virtual en la base y override en la derivada.
class Animal {
public:
virtual ~Animal() = default;
virtual void sonido() const {
std::cout << "Sonido generico\n";
}
};
class Perro : public Animal {
public:
void sonido() const override {
std::cout << "Guau\n";
}
};
Punto tecnico importante¶
override aplica a metodos virtuales, no a constructores.
Abstraccion¶
La abstraccion se enfoca en lo esencial y define contratos.
Clase abstracta con metodo virtual puro:
- No puedes instanciar
Animal. - Toda clase derivada concreta debe implementar
sonido().
Ejemplo completo: lista heterogenea de animales¶
Version moderna (recomendada) con std::unique_ptr:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Animal {
public:
virtual ~Animal() = default;
virtual void sonido() const = 0;
};
class Perro : public Animal {
public:
void sonido() const override { std::cout << "Guau\n"; }
};
class Gato : public Animal {
public:
void sonido() const override { std::cout << "Miau\n"; }
};
int main() {
std::vector<std::unique_ptr<Animal>> animales;
animales.push_back(std::make_unique<Perro>());
animales.push_back(std::make_unique<Gato>());
for (const auto& a : animales) {
a->sonido();
}
}
Definiciones teoricas (resumen extendido)¶
1) Objeto¶
Un objeto es cualquier entidad que quieras modelar en tu programa como tipo de dato:
- fisica: celular, auto, mascota
- virtual: ticket digital, turno medico, orden de compra
Todo objeto combina:
- estado (atributos),
- comportamiento (metodos).
2) Clase¶
Una clase es el molde/tipo que define:
- que datos tiene el objeto,
- que operaciones puede ejecutar.
Al crear variables de ese tipo, creas instancias (objetos).
3) Atributo y metodo¶
- atributo: dato interno del objeto (ej:
peso) - metodo: funcion asociada al objeto (ej:
sonido())
4) Instanciacion¶
Declarar un objeto se parece a declarar una variable:
Animal es el tipo, perro es la instancia.
5) Constructor¶
Metodo especial de inicializacion que corre al crear el objeto.
- no tiene tipo de retorno,
- se llama igual que la clase.
Sirve para evitar bloques largos de asignaciones despues de crear el objeto.
6) Encapsulacion¶
Encapsular es proteger el estado interno y exponer solo la interfaz necesaria.
Objetivo:
- evitar cambios invalidos desde fuera,
- centralizar validaciones,
- mantener invariantes del objeto.
7) Getters y setters¶
Permiten acceso controlado a atributos no publicos.
Convencion comun:
getAtributo()setAtributo(valor)
Un setter puede incluir reglas de negocio (ej: no permitir peso negativo).
8) Modificadores de acceso¶
public: accesible desde cualquier parte.private: accesible solo dentro de la clase.protected: accesible dentro de la clase y sus derivadas.
Nota: en class, si no especificas acceso, el default es private.
9) Herencia¶
Permite reutilizar comportamiento comun en una clase base y especializar en clases hijas.
La hija puede:
- agregar atributos/metodos,
- redefinir metodos virtuales,
- usar miembros
public/protectedheredados.
10) Tipo de herencia y restriccion de acceso¶
Heredar con public, protected o private no hace "mas publico" nada; solo mantiene o restringe:
- herencia
public: conserva visibilidad heredada (publicsiguepublic) - herencia
protected: lopublicdel padre pasa aprotected - herencia
private: lopublic/protecteddel padre pasa aprivate
private del padre nunca es accesible directo desde la hija.
11) Polimorfismo¶
Misma llamada, distinto comportamiento segun tipo real del objeto.
En C++ clasico:
- base con metodo
virtual, - derivada con
override.
Regla clave: override aplica a metodos virtuales, no a constructores.
12) Abstraccion¶
Quedarte con lo esencial del dominio y modelar contratos.
En C++, una clase abstracta se crea con metodos virtuales puros (= 0) y:
- no puede instanciarse,
- obliga a derivadas concretas a implementar el contrato.
13) Colecciones polimorficas¶
Para mezclar Perro, Gato, etc. en un mismo contenedor:
- el contenedor debe ser de tipo base (
Animal*o smart pointer aAnimal), - las llamadas virtuales se resuelven segun tipo dinamico.
14) Memoria dinamica en este contexto¶
Con punteros crudos:
newrequieredelete,- riesgo de leaks/double free si no hay disciplina.
Con C++ moderno:
- preferir
std::unique_ptrystd::make_unique.
15) Correcciones tecnicas del guion (importante)¶
- Decir "el constructor se sobreescribe" es incorrecto: los constructores no son virtuales.
- Lo correcto es: la clase derivada define su propio constructor y llama al constructor base en la lista de inicializacion.
overridecorrecto se escribeoverride(nooverridge).
Relacion con reversing (pista rapida)¶
Cuando hay polimorfismo en C++ suelen aparecer:
- tablas virtuales (vtable),
- punteros a vtable dentro del objeto,
- llamadas indirectas a metodos virtuales.
Cuando no hay virtuales, normalmente veras llamadas directas a metodos concretos.
Checklist practico de POO en C++¶
- Usa atributos
privateoprotected. - Expon solo metodos necesarios en
public. - Inicializa con constructores claros.
- Para herencia, inicializa la base en lista de inicializacion.
- Para polimorfismo, usa
virtual+override. - Si usas punteros, prefiere smart pointers (
unique_ptr) anew/deletemanual.
Errores comunes¶
- Confundir constructor con metodo virtual.
- Intentar acceder desde hija a miembros
privatedel padre. - Guardar objetos derivados por valor en contenedores de base (object slicing).
- Usar
newsin estrategia de liberacion.