Descargar la presentación
La descarga está en progreso. Por favor, espere
Publicada porEsteban Maidana Villanueva Modificado hace 9 años
1
Sobrecarga de operadores Pablo San Segundo (C-206) pablo.sansegundo@upm.es
2
Introducción En C++ admite sobrecarga de funciones (polimorfismo de nombre) p.ej. constructores sobrecargados en ejemplos vistos C++ también admite sobrecarga de operadores Un operador es una función con una definición especial (palabra clave operator) Se pueden sobrecargar la mayoría de los operadores para adaptarlos a operaciones entre objetos La sobrecarga puede ser mediante función independiente o mediante función miembro Nota: En ANSI C ya se realizaba sobrecarga pero estaba predefinida para diferentes tipos base. Por ejemplo, el operador ‘+’ significa cosas distintas dependiendo si se aplica a enteros o dobles Punto operator + (Punto p1, Punto p2);
3
Ejemplo: clase punto2D Declaración (punto.h) class Punto{ double x, y; public: Punto(double x, double y); void print(){cout<<"("<<x<<","<<y<<")"<<endl;} //… friend Punto operator + (const Punto& p1, const Punto& p2); }; Definición (punto.cpp) Punto operator+(const Punto& p1, const Punto& p2){ Punto pres(p1); pres.x += p2.x; pres.y += p2.y; return pres; } Test Unitario (*.cpp) void main(){ Punto p(5.0, 10.0); Punto w(10.0, 15.0); cout<<"La suma es:"; (p+w).print_punto(); } EJERCICIO Para una clase que encapsula puntos 2D defínase la operación suma entre puntos EJERCICIO ¿Salida en pantalla? CUESTIÓN ¿Existe constructor adecuado?
4
Sintaxis y tipos Tipos Sobrecarga mediante función independiente Sobrecarga mediante función miembro operator ( ); Declaración (punto.h) class Punto{ double x, y; public: //… //función independiente anterior friend Punto operator + (const Punto& p1, const Punto& p2); //función miembro Punto operator + (const Punto& p1); }; Cuestión ¿Pueden coexistir a la vez?
5
Limitaciones (1/2) La sobrecarga debe tener al menos un argumento enumerado o estructurado Algunos operadores no se pueden sobrecargar Algunos operadores solo pueden sobrecargarse como funciones miembro REGLA: No se pueden sobrecargar operadores sólo con argumentos de tipo base.,::?: newdelete=[]-> float operator + (float a, float b); Cuestión ¿Es un prototipo válido?
6
Limitaciones (2/2) Es necesario conservar el número de argumentos del operador predefinido para los tipos base Un operador función miembro recibe obligatoriamente como primer argumento el objeto que lo llama C++ preserva la prioridad relativa y asociatividad del operador original No presuponga comportamientos sobrecarga de * conmutativa modificación de un valor += !&*+-++-- EJERCICIO Sobrecargue el operador ! (NOT lógico) como función miembro de la clase Punto para que devuelva TRUE si el punto es el origen de coordenadas Operadores unarios ¡ATENCIÓN AL DISEÑO!
7
Interpretación de la sobrecarga Operador sobrecargado independiente Operadores sobrecargado miembro TEST UNITARIO (*.cpp) void main(){ Punto p, w; //… (p+w). print_punto(); operator+(p,w).print_punto(); } TEST UNITARIO (*.cpp) void main(){ Punto p, w; //… (p+w). print_punto(); ( p.operator+(w)).print_punto(); }
8
Argumentos de tipo base EJERCICIO Declare e implemente operadores de traslación positiva y negativa de un valor constante k unidades para la clase Punto de los ejemplos anteriores. CUESTIÓN Si el prototipo de la sobrecarga tiene la traslación positiva de k unidades como primer argumento, ¿se puede definir como función miembro? CUESTIÓN ¿Es el operador translación que ha definido conmutativo?
9
Cuestiones de diseño de operadores(I) Algunas consideraciones Si la semántica del operador no es evidente NO lo implemente Siempre ofrezca el conjunto de operaciones relacionadas con el operador p. ej. si se ofrece +, también debe ofrecerse += No altere el comportamiento “intuitivo” del operador
10
Cuestiones de diseño de operadores(II) Función miembro vs. Función independiente Si el primer argumento del operador no es del tipo de la clase NO puede ser función miembro Si el operador es monario, impleméntelo como función miembro Si el operador es binario y no modifica los operandos, impleméntelo como función independiente Si el operador es binario y modifica el operando de la izquierda, impleméntelo como función miembro Emplee las soluciones “canónicas” que existen para algunos operadores
11
Diseño de operadores (I) Operador asignación = Existe un operador predeterminado (shallow copy) class X{ X& X::operator=(const X& rhs){ if (this != &rhs){ //do the assignment } return *this; } }; EJERCICIO Sobrecargue el operador para puntos 2D
12
Forma canónica de una clase Constructor Destructor Constructor copia Operador asignación Declaración (foo.h) class Foo{ public: Foo(//…); ~Foo(//…); Foo(const Foo& ); Foo& operator =(const Foo&); }; CUESTIÓN Implemente la forma canónica para la clase Punto 2D de ejemplos anteriores
13
Diseño de operadores (II) Operadores para flujos > std::ostream& operator<<(std::ostream& os, const T& obj) { // write obj. to stream return os; } std::istream& operator>>(std::istream& is, T& obj) { // read obj. from stream if( /* no valid object of T found in stream */ ) is.setstate(std::ios::failbit); return is; } EJERCICIO Sobrecargue el operador para visualizar la clase punto 2D en pantalla
14
Diseño de operadores (III) Comparadores, >=, ==, != inline bool operator==(const X& lhs, const X& rhs){ /* do actual comparison */ } inline bool operator!=(const X& lhs, const X& rhs){return !operator==(lhs,rhs);} inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ } inline bool operator> (const X& lhs, const X& rhs){return operator< (rhs,lhs);} inline bool operator (lhs,rhs);} inline bool operator>=(const X& lhs, const X& rhs){return !operator< (lhs,rhs);} EJERCICIO Defina adecuadamente algunos de estos operadores para la clase punto 2D
15
Diseño de operadores (IV) Operadores Aritméticos Binarios class X { X& operator+=(const X& rhs) { // actual addition of rhs to *this return *this; } }; inline X operator+(X lhs, const X& rhs) { lhs += rhs; return lhs; } Si se ofrece el + incluya el += Si se ofrece el -, incluya el -= …
16
Diseño de operadores (V) Operadores Aritméticos Unarios class X { X& operator++() { // do actual increment return *this; } X operator++(int) { X tmp(*this); operator++(); return tmp; } }; EJERCICIO Para un punto 2D en el origen de coordenadas implemente ambos operadores y compruebe su correcto funcionamiento con el operador !
17
Diseño de operadores (VI) Operador subíndice [ ] class X { value_type& operator[](index_type idx); const value_type& operator[](index_type idx) const; //... }; EJERCICIO Sobrecargue el operador para una clase que gestiona colecciones de puntos 2D
18
Diseño de operadores (VII) Operador functor ( ) Permite definir objetos que se comportan como funciones (Functors) class X { public: bool operator()(int a, int b) const { return a<b;} }; void foo(int a, int b, const X& x){ if(x(a, b)){ cout<<a<<" menor que "<<b<<endl; } //test unitario void main (){ foo(10, 20, X()); } CUESTIÓN Salida en pantalla
19
CASOS PRÁCTICOS
20
Envoltorio para manejar archivos Implemente una clase File “wrapper” para facilitar la lectura y escritura de archivos en C++ class File{ fstream m_f; public: enum mode_t{READ, WRITE, APPEND}; File(const char* name, mode_t type); File(const char* name, const char* text, mode_t type); ~File(); fstream& get_file(); void print(); stringstream read(int num_char=250); stringstream read_line(int num_char=250); void close(); };
21
Sudoku Implemente una clase Sudoku que lea un sudoku desde fichero en diferentes formatos y lo almacene en una matriz 9x9 class Sudoku{ enum type_t{EMPTY=0, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE}; static const int SUDOKU_ERROR=-1; static const int SUDOKU_OK=0; type_t ** board; public: friend ostream& operator<<(ostream& o, const Sudoku& s); static const int SUDOKU_ROWS=9; Sudoku(); ~Sudoku(); int add_number(int i, int j, type_t val); void reset(); int read_compressed_format(char* filename); int read_standard_format(char* filename); };
22
¡ESTO ES TODO!
Presentaciones similares
© 2025 SlidePlayer.es Inc.
All rights reserved.