Skip to content

Instantly share code, notes, and snippets.

@lucasp90
Created April 18, 2017 23:23
Show Gist options
  • Save lucasp90/3de0591a7924cbfa03a1061daeb6427c to your computer and use it in GitHub Desktop.
Save lucasp90/3de0591a7924cbfa03a1061daeb6427c to your computer and use it in GitHub Desktop.
apuntes-clase-6.md

Taller de Programación I - Clase 6

Clases (parte 2)

class A {
private:
  int pri;
protected:
  int pro;
public:
  int pub;
}


class B: public A {
  int foo() {
    this->pro = 0;
    this->pub = 0;
    this->priv = 0; // NO SE PUEDE
  }
}

B b;
b.pub = 0;
b.pro = 0;
b.priv = 0;

class C: protected A {
  // Restringimos el acceso a los atributos de la clase base
  int p() {
    this->pub = 0;
    this->pro = 0;
    this->priv = X; // no se puede acceder
  }
}
  • Filas: atributos - métodos
  • Columnas: tipo de herencia

| | public | protected | private | |---------------------------------------------| | public | PUBLIC | PROTECTED | PRIVATE | | protected | PROTECTED | PROTECTED | PRIVATE | | private | - | - | - |

Polimorfismo en herencias múltiples

  • En caso de que las clases hereden de varias clases que tengan métodos con nombres similares, implica que hay que desambiguar y definir explícitamente a qué método queremos llamar.
  • En caso de que las clases sobre las que se hereda hereden de una misma clase, se duplican las variables, dado que cada clase genera su propio espacio de variables.
  1. A hereda de base: Genera su propio espacio de variables (con las properties de BASE)
  2. B hereda de base: Genera su propio espacio de variables (con las properties de BASE)
  3. C hereda de A y B: En su espacio de variables tiene las variables de A y de B, o sea, tiene dos veces las properties de BASE.

Esto se llama herencia diamante.

class Radio: public virtual Transmitter, public virtual Receiver {

  virtual void m() {
    Transmitter::m();
  }
}

Manejo de errores en c++

Hasta ahora manejamos los errores utilizando un código de error para comunicar al usuario que la función ha fallado en su ejecución. Hay algunos problemas al respecto:

  • Si se realizan operaciones tales como reserva de memoria o apertura de archivos, hay que efectuar la operación inversa por cada operación exitosa
  • El código se complejiza

Excepciones y su mal uso

Se pueden lanzar excepciones (que pueden ser tranquilamente números enteros) y catchear excepciones, pero tranquilamente puede terminar siendo una seguidilla de ifs.

RAII

  • Usando RAII se puede controlar errores en los constructores. Si pincha algún constructor, se lanza la excepción y se disparan todos los destructores de los objetos creados hasta el momento, no hay necesidad de catchear y encargarse de destruir las cosas manualmente.
  • Un buen uso de RAII nos permite programar el camino feliz sin tanto chequeo "a mano".
  • Si el constructor falla NO SE LLAMA AL DESTRUCTOR. Para eso hay que usar RAII sobre RAII (ver el ejemplo de DoubleBuffer y su member initalization list)
  • std::uniq_ptr<T>: punteros RAII. referencia.
  • NO LANZAR EXCEPCIONES EN UN DESTRUCTOR: Si se lanza una excepcion y se dispara el destructor, este puede lanzar otra excepción y a c++ no le gusta esto...

Exception safety

Hay distintos niveles de seguridad para mantener los objetos en estado válido al momento de ser modificados:

  • Unsafe: Si un método que modifica deja el objeto en estado inválido, se tira una excepción pero el objeto queda inválido.
  • Exception safe weak: Si un método que modifica el objeto está por dejarlo en estado inválido, se lanza una excepción justo antes de invalidarlo. Esto puede modificar "a medias" un objeto.
  • Exception safe strong: Si se modifica el objeto, se lanza una excepción que preserva el estado original.

Tips

  • Lanzar excepciones con mensajes que tengan la mayor cantidad de información para que el debugging sea más sencillo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment