AnteriorPosterior

14. Sobrecarga de operadores. Funciones amigas

  Curso: Introducción a C++, por Nacho Cabanes (antiguo)

14. Sobrecarga de operadores. Funciones amigas.

Una de las posibilidades de C++ que todavía no hemos visto y que ayuda mucho a mejorar la legibilidad de los programas es la "sobrecarga de operadores".

Hemos visto como sobrecargar (redefinir) funciones, de modo que una misma función se puede comportar de formas distintas, según los parámetros que le pasemos. Ahora vamos a intentar hacer lo mismo: "sobrecargar" (redefinir) operadores como +, - *, <<, etc., para que nos permitan sumar dos objetos que nosotros hayamos creado. Veremos también una introducción a las funciones amigas y a las clases amigas.

Vamos allá...

Usaremos uno de los ejemplos típicos: vamos a crear una clase que será un Vector en el plano, definido por las dos coordenadas X e Y de su extremo (el origen del vector lo consideraremos situado en el origen de coordenadas). Nuestro objetivo será sumar vectores usando el operador + y mostrar vectores en pantalla usando el operador <<.

Comenzaremos haciendolo "a la manera tradicional": si no sabemos redefinir cosas como + y <<, lo que haríamos sería definir un método "Sumar" y otro método "Mostrar", así:


  1:  // 
2:
// sobrec01.cpp
3:
//
4:
// Introduccion a C++
5:
// Sobrecarga de operadores: aproximación
6:
// Probado con TC++ (MsDos)
7:
//
8:
// Curso de C
9:
// Jose Ignacio Cabanes
10:
//
11:
/////////////////////////////////////////////
12:

13: #include <iostream.h>
14:
15: // ---------------------------------------------------------
16:
// CLASE : NVector
17:
// Vector, determinado por las dos coordenadas de su
18:
// extremo (se supone su origen en el origen de
19:
// coordenadas)
20:
// ---------------------------------------------------------
21:

22: class NVector {
23:
24: int coordX, coordY; // Coordenadas del extremo del vector
25:

26: public:
27:
28: int LeerX(); // Leer valores y fijarlos
29:
int LeerY();
30: void FijarX( int valor );
31: void FijarY( int valor );
32:
33: void Mostrar(); // Mostrar en pantalla: (x,y)
34:
void Sumar( NVector v2 ); // Sumar otro vector a éste
35:
};
36:
37: // ==========================================================================
38:

39: //
40:
// A continuación viene el desarrollo de las funciones (métodos)
41:
//
42:
// ========
43:

44: /* ----------------- NVector ------------------------------- */
45: /* Leer los valores de las coordenadas */
46: /* _________________________________________________________ */
47:
48: int
49: NVector::LeerX() {
50: return coordX;
51: }
52:
53: int
54: NVector::LeerY() {
55: return coordY;
56: }
57:
58:
59: /* ----------------- NVector ------------------------------- */
60: /* Fijar los valores de las coordenadas */
61: /* _________________________________________________________ */
62:
63: void
64: NVector::FijarX( int valor ) {
65: coordX = valor;
66: }
67:
68: void
69: NVector::FijarY( int valor ) {
70: coordY = valor;
71: }
72:
73:
74: /* ----------------- NVector ------------------------------- */
75: /* Otras: mostrar y sumar */
76: /* _________________________________________________________ */
77:
78: void
79: NVector::Mostrar() {
80: cout << "(" << coordX << "," << coordY << ")\n";
81: }
82:
83: void
84: NVector::Sumar( NVector v2 ) {
85: coordX += v2.coordX;
86: coordY += v2.coordY;
87: }
88:
89:
90:
91:
92:
93: // ==========================================================================
94:
//
95:
// Finalmente: un programa sencillo de ejemplo
96:
//
97:
// ========
98:

99: NVector vec1, vec2; // Definimos dos objetos de la clase "NVector"
100:

101: main() {
102: vec1.FijarX(3); vec1.FijarY(2);
103: vec1.Mostrar();
104:
105: vec2.FijarX(5); vec2.FijarY(4);
106: vec2.Mostrar();
107:
108: vec1.Sumar(vec2);
109: vec1.Mostrar();
110: return 0;
111: }


En principio, no debería haber ninguna dificultad con este programa. He conservado todo en un único fuente, aunque no sea lo más correcto, buscando una mayor legibilidad, ya que vamos a ver conceptos nuevos.

Eso sí, por lo menos he intentado favorecer un poco la encapsulación mediante las funciones miembro LeerX, LeerY, FijarX, FijarY, de modo que no sea necesario acceder directamente a las variables miembro, que he definido como privadas.

El resultado de este programa debería ser algo así:

(3,2)
(5,4)
(8,6)

Mejorémoslo. La primera aproximación se va a parecer ya mucho a lo que buscamos: vamos a redefinir el operador +, de modo que podamos escribir vec1 = vec1 + vec2. La idea será simplemente crear una función llamada "operator+", en vez de la función "Sumar" que teníamos, así:

  1:  // 
2:
// sobrec02.cpp
3:
//
4:
// Introduccion a C++
5:
// Sobrecarga de operadores: ejemplo
6:
// Probado con TC++ (MsDos)
7:
//
8:
// Curso de C
9:
// Jose Ignacio Cabanes
10:
//
11:
/////////////////////////////////////////////
12:

13: #include
<iostream.h>
14:
15:
// ---------------------------------------------------------
16:
// CLASE : NVector
17:
// Vector, determinado por las dos coordenadas de su
18:
// extremo (se supone su origen en el origen de
19:
// coordenadas)
20:
// ---------------------------------------------------------
21:

22:
class NVector {
23:
24:
int coordX, coordY; // Coordenadas del extremo del vector
25:

26:
public:
27:
28: NVector
() { coordX = 0; coordY = 0; } // Constructor
29:

30:
int LeerX(); // Leer valores y fijarlos
31:
int LeerY();
32:
void FijarX( int valor );
33:
void FijarY( int valor );
34:
35:
void Mostrar(); // Mostrar en pantalla: (x,y)
36:
NVector operator+( NVector v2 ); // Sumar otro vector a "šste
37:
};
38:
39:
// ==========================================================================
40:

41:
//
42:
// A continuación viene el desarrollo de las funciones (métodos)
43:
//
44:
// ========
45:

46:
/* ----------------- NVector ------------------------------- */
47:
/* Leer los valores de las coordenadas */
48:
/* _________________________________________________________ */
49:
50:
int
51: NVector
::LeerX() {
52:
return coordX;
53:
}
54:
55:
int
56: NVector
::LeerY() {
57:
return coordY;
58:
}
59:
60:
61:
/* ----------------- NVector ------------------------------- */
62:
/* Fijar los valores de las coordenadas */
63:
/* _________________________________________________________ */
64:
65:
void
66: NVector
::FijarX( int valor ) {
67: coordX
= valor;
68:
}
69:
70:
void
71: NVector
::FijarY( int valor ) {
72: coordY
= valor;
73:
}
74:
75:
76:
/* ----------------- NVector ------------------------------- */
77:
/* Otras: mostrar y sumar */
78:
/* _________________________________________________________ */
79:
80:
void
81: NVector
::Mostrar() {
82: cout
<< "(" << coordX << "," << coordY << ")\n";
83:
}
84:
85: NVector
86: NVector
::operator +( NVector v2 ) {
87: NVector temporal
;
88:
89: temporal
.coordX = coordX + v2.coordX;
90: temporal
.coordY = coordY + v2.coordY;
91:
92:
return temporal;
93:
}
94:
95:
96:
97:
98:
99:
// ==========================================================================
100:
//
101:
// Finalmente: un programa sencillo de ejemplo
102:
//
103:
// ========
104:

105: NVector vec1
, vec2; // Definimos dos objetos de la clase "NVector"
106:

107:
main() {
108: vec1.FijarX
(3); vec1.FijarY(2);
109: vec1.Mostrar
();
110:
111: vec2.FijarX
(5); vec2.FijarY(4);
112: vec2.Mostrar
();
113:
114: vec1
= vec1 + vec2;
115: vec1.Mostrar
();
116:
return 0;
117:
}

No parece difícil, ¿verdad? Lo único que hemos hecho es crear una función llamada "operator+", que devuelve un NVector (bueno, y también hemos añadido un constructor, que inicializa a 0 las dos componentes del vector).

Eso sí, esto no funcionará si en vez de escribir "vec1 = vec1 + vec2" usamos la notación abreviada "vec1 += vec2". La forma de solucionarlo sería redefiniendo también el operador += de la siguiente forma

NVector& operator+=( NVector v2 ) { // Válido para vec1 = vec1 + vec2
return *this = *this + v2;
}

En la definición de este operador me he apoyado en la del operador +. que ya estaba definido. He empleado el puntero this, que es un puntero especial, que hace referencia al objeto que ha generado la llamada. Este puntero se le pasa implícitamente a todas las funciones miembro.

Para sobrecargar el operador <<, antes vamos a ver una introducción a las funciones y clases amigas...



Actualizado el: 13-08-2006 21:14

AnteriorPosterior