Fundamentos Avanzados C++: Herencia, Sobrecarga de Operadores, Plantillas y Gestión de Memoria
Clasificado en Informática
Escrito el en español con un tamaño de 6,33 KB
1. Clases, Herencia y Atributos de Objetos
Sea la siguiente definición de clases:
Definición de Clases
class C1 {
protected:
int x1, x2;
public:
C1() { x1 = 5; x2 = 6; }
C1(int x3) { x1 = x3; x2 = 2 * x3; }
};
class C2 : public C1 {
public:
C2() { x2 = 7; }
C2(int x4) : C1(x4 + 8) {
x1 = x4 - 2;
}
};
class C3 : public C2 {
public:
int x5;
public:
C3() { x5 = 9; }
C3(int x6) : C2(x6 + 10) {
x5 = x6 + 3;
}
};
Y sea la siguiente declaración de objetos:
Declaración de Objetos
C1 obj1; C1 obj2(3); C2 obj3; C2 obj4(2); C3 obj5; C3 obj6(1);
Indica los valores de TODOS los atributos de los objetos:
Valores de los Atributos de los Objetos
- Atributos de obj1:
x1 = 5, x2 = 6
- Atributos de obj2:
x1 = 3, x2 = 6
- Atributos de obj3:
x1 = 5, x2 = 7
- Atributos de obj4:
x1 = 0, x2 = 20
- Atributos de obj5:
x1 = 5, x2 = 7, x5 = 9
- Atributos de obj6:
x1 = 9, x2 = 38, x5 = 4
2. Sobrecarga de Operadores: Clase Complejo
Dada la clase Complejo
, modifica la definición de la clase y define los métodos y funciones necesarios para sobrecargar los operadores +
y <<
de manera que se puedan sumar y mostrar por pantalla (o guardar en un fichero) objetos de la clase.
Definición Original de la Clase Complejo
class Complejo {
private:
float real, imag;
public:
Complejo() { real = imag = 0; }
Complejo(float r, float i) { real = r; imag = i; }
void mostrar() { cout << real << "+i" << imag; }
};
Ejemplo de Uso Deseado
Complejo c1(1.0, 2.0), c2, c3(5.0, 6.0);
c2 = c1 + c3;
cout << c2 << endl; // Muestra por pantalla: 6+i8
Definición Modificada de la Clase Complejo
class Complejo {
private:
float real, imag;
public:
Complejo() { real = imag = 0; }
Complejo(float r, float i) { real = r; imag = i; }
void mostrar() { cout << real << "+i" << imag; }
// Declaración de la sobrecarga del operador de suma
Complejo operator+(const Complejo &);
// Declaración de la sobrecarga del operador de inserción (friend function)
friend ostream & operator<<(ostream &, const Complejo &);
};
Implementación de los Operadores Sobrecargados
Complejo Complejo::operator+(const Complejo &c) {
Complejo res;
res.real = real + c.real;
res.imag = imag + c.imag;
return res;
}
ostream & operator<<(ostream &os, const Complejo &c) {
os << c.real << "+i" << c.imag;
return os;
}
3. Plantilla de Función para Eliminación en Vectores STL
Escribe una plantilla de función que permita eliminar los elementos de un contenedor vector
(de la STL) de tipo genérico que contengan un cierto valor. La función recibirá a través del primer parámetro el vector y a través del segundo el valor a eliminar, y devolverá a través del primer parámetro el vector modificado donde han sido eliminados los elementos con ese valor (el del 2º parámetro).
Ejemplo de Uso de la Plantilla
vector<int> vi; vector<string> vs;
// ... (Suponiendo que el contenido de vi es: 1 0 3 7 0 6)
eliminar(vi, 0); // Ahora es: 1 3 7 6
// ... (Suponiendo que el contenido de vs es: "Ana" "Pepe" "Eva" "Pepe" "Sara")
string cad = "Pepe";
eliminar(vs, cad); // Ahora es: "Ana" "Eva" "Sara"
Implementación de la Plantilla de Función
template <class TValor>
void eliminar(vector<TValor> &v, TValor val) {
vector<TValor> res;
for (int i = 0; i < v.size(); i++) {
if (v[i] != val) {
res.push_back(v[i]);
}
}
v = res;
return;
}
4. Manejo de Memoria y Copia de Objetos: Clase Saco
Dado el siguiente programa:
Definición Original de la Clase Saco
class Saco {
private:
int tam, *datos;
void reserva(int t) {
tam = t;
datos = new int[t];
}
public:
Saco(int t = 1) {
reserva(t);
for (int i = 0; i < t; i++) {
datos[i] = t;
}
}
~Saco() { delete[] datos; }
void imprime() {
for (int i = 0; i < tam; i++) {
cout << datos[i] << " ";
}
}
void setDato(int i, int val) {
datos[i] = val;
}
};
Función Principal (main)
int main() {
Saco *p1 = new Saco(4);
p1->setDato(0, 2);
p1->setDato(1, 4);
p1->setDato(2, 6);
p1->setDato(3, 8);
Saco s2, s1 = *p1;
s2 = s1;
delete p1;
s1.imprime();
s2.imprime();
return 0;
}
Añade en la definición de la clase los métodos necesarios (sin modificar los que ya existen) de manera que el programa funcione correctamente y escriba dos veces por pantalla: 2 4 6 8
.
Implementación de Constructor Copia y Operador de Asignación
class Saco {
// ... (miembros existentes)
// Redefinición del constructor copia
Saco(const Saco &);
// Redefinición del operador asignación
const Saco & operator=(const Saco &);
};
Definición del Constructor Copia
Saco::Saco(const Saco &s) {
reserva(s.tam);
for (int i = 0; i < tam; i++) {
datos[i] = s.datos[i];
}
}
Definición del Operador de Asignación
const Saco & Saco::operator=(const Saco &s) {
if (this != &s) { // Evitar auto-asignación
if (datos != NULL) { // Liberar memoria existente si la hay
delete[] datos;
}
reserva(s.tam); // Reservar nueva memoria
for (int i = 0; i < tam; i++) {
datos[i] = s.datos[i]; // Copiar datos
}
}
return *this; // Devolver referencia al objeto actual
}