402y37

Ejemplos capítulos 27 a 31

Ejemplo 31.1
Ahora estamos en disposición de empezar a usar clases para modelar algunos problemas cotidianos.
Empezaremos por las fracciones. Ya hemos hecho algunas aproximaciones usando estructuras, ahora usaremos una clase, y en sucesivos capítulos, iremos añadiendo más refinamientos.
// Clase fracción
//Mayo 2015 Tutoriales En Linea


#include <iostream>

using namespace std;

class fraccion {
    public:
        fraccion(int n=0, int d=0) : numerador(n), denominador(d) {
            Simplificar();
        }
        void Simplificar();
        void Mostrar();
    private:
        int numerador;
        int denominador;
        int MCD(int, int);
};

void fraccion::Simplificar() {
    int mcd = MCD(numerador, denominador);
    numerador /= mcd;
    denominador /= mcd;
}

void fraccion::Mostrar() {
    cout << numerador << "/" << denominador << endl;
}

int fraccion::MCD(int a, int b) {
    if(a < b) return MCD(b,a);
    if(b == 0) return a;
    return MCD(b, a % b);
}

int main() {
    fraccion f1(234, 2238);
    fraccion f2(64, 1024);
    
    f1.Mostrar();
    f2.Mostrar();
    return 0;
} 
Ejecutar este código en codepad.

Hemos invocado al método Simplificar dentro del constructor, de ese modo, la fracción siempre se almacenará simplificada cuando se cree. Probablemente esto haga que sea innecesario que Simplificar sea pública, ya que cualquier llamada desde el exterior no afectará a la fracción. Podríamos haberla declarado como privada.

Ejemplo 31.2
Añadamos una función Sumar a esta clase, que nos sirva para sumar dos fracciones:

// Clase fracción
// Mayo 2015 Tutoriales En Linea

#include <iostream>

using namespace std;

class fraccion {
    public:
        fraccion(int n=0, int d=0) : numerador(n), denominador(d) {
            Simplificar();
        }
        void Simplificar();
        void Sumar(fraccion);
        void Mostrar();
    private:
        int numerador;
        int denominador;
        int MCD(int, int);
};

void fraccion::Simplificar() {
    int mcd = MCD(numerador, denominador);
    numerador /= mcd;
    denominador /= mcd;
}

void fraccion::Sumar(fraccion f2) {
    numerador = numerador*f2.denominador+denominador*f2.numerador;
    denominador = denominador*f2.denominador;
    Simplificar();
}

void fraccion::Mostrar() {
    cout << numerador << "/" << denominador << endl;
}

int fraccion::MCD(int a, int b) {
    if(a < b) return MCD(b,a);
    if(b == 0) return a;
    return MCD(b, a % b);
}

int main() {
    fraccion f1(234, 2238);
    fraccion f2(64, 1024);
    
    f1.Mostrar();
    f2.Mostrar();

    f1.Sumar(f2);
    f1.Mostrar();

    return 0;
}
Ejecutar este código en codepad.

Más adelante veremos como sobrecargar el operador suma para implementar esta función.

Ejemplo 31.3
En este ejemplo crearemos una clase "tonta", que nos servirá para seguir la pista a constructores y destructores a medida que son invocados de forma implícita o explícita. En próximos capítulos añadiremos más cosas para monitorizar otras características.
// Clase tonta
// Mayo 2015 Tutoriales En Linea

#include <iostream>

using namespace std;

class tonta {
    public:
        tonta();
        tonta(int);
        tonta(const tonta&);
        ~tonta();
        int Modifica(int);
        int Lee();
    private:
        int valor;
};

tonta::tonta() : valor(0) {
    cout << "Constructor sin parámetros (0)" << endl;
}

tonta::tonta(int v) : valor(v) {
    cout << "Constructor con un parámetro (" << v << ")" << endl;
}

tonta::tonta(const tonta &t) : valor(t.valor) {
    cout << "Constructor copia (" << t.valor << ")" << endl;
}

tonta::~tonta() {
    cout << "Destructor (" << valor << ")" << endl;
}

int tonta::Modifica(int v) {
    int retval = valor;

    cout << "Modificar valor (" << valor << ") -> (" << v << ")" << endl;
    valor = v;
    return retval;
}

int tonta::Lee() {
    return valor;
}

int main() {

    tonta obj1;
    tonta *obj2;
    tonta obj3 = obj1;

    obj2 = new tonta(2);

    obj1.Modifica(3);
    cout << "Objeto1: " << obj1.Lee() << endl;
    cout << "Objeto2: " << obj2->Lee() << endl;
    cout << "Objeto3: " << obj3.Lee() << endl;

    delete obj2;

    return 0;
} 
Ejecutar este código en codepad.
Viendo la salida de este programa:
Constructor sin parámetros (0)
Constructor copia (0)
Constructor con un parámetro (2)
Modificar valor (0) -> (3)
Objeto1: 3
Objeto2: 2
Objeto3: 0
Destructor (2)
Destructor (0)
Destructor (3) 
vemos que para obj1 se invoca al constructor sin parámetros cuando es declarado, y que para obj2 se invoca al constructor con un parámetro cuando es invocado explícitamente junto al operador new.

Con los destructores pasa lo mismo, para obj2 se incova al destruir el objeto mediante el operador delete, y para obj1 se invoca de forma implícita al terminar su ámbito temporal.
Ir al Principio
Compartir

Mi nombre es Alexander fundador y CEO, y me gusta llamarme un Geek. Amo la informática, tecnología y todo lo que está relacionado con ella. Inicié este sitio con la intención de compartir conocimientos como cursos en línea, tutoriales y videotutoriales. Estoy muy entusiasmado con la información que he descubierto y compartido hasta el momento. La verdad es que lo he hecho con el mayor de los gustos. Así es, soy un Geek con una visión para compartir conocimiento. Leer mas...