Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO

arco.esi.uclm.es
from arco.esi.uclm.es More from this publisher
13.01.2015 Views

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 370 — #408 ✐ Capítulo 12. Sobrecarga de operadores 12.6.3. Ejemplo de conversión de tipos Un ejemplo en el que la conversión automática de tipos es extremadamente útil es con cualquier clase que encapsule una cadena de caracteres (en este caso, simplemente implementaremos la clase usando la clase estándar de C++ string dado que es simple). Sin la conversión automática de tipos, si quiere usar todas las funciones existentes de string de la librería estándar de C, tiene que crear un método para cada una, así: //: C12:Strings1.cpp // No auto type conversion #include "../require.h" #include #include #include using namespace std; class Stringc { string s; public: Stringc(const string& str = "") : s(str) {} int strcmp(const Stringc& S) const { return ::strcmp(s.c_str(), S.s.c_str()); } // ... etc., for every function in string.h }; int main() { Stringc s1("hello"), s2("there"); s1.strcmp(s2); } ///:~ Aquí, sólo se crea la función strcmp(), pero tendría que crear las funciones correspondientes para cada una de que necesite. Afortunadamente, puede proporcionar una conversión automática de tipos permitiendo el acceso a todas las funciones de . //: C12:Strings2.cpp // With auto type conversion #include "../require.h" #include #include #include using namespace std; class Stringc { string s; public: Stringc(const string& str = "") : s(str) {} operator const char*() const { return s.c_str(); } }; int main() { 370 ✐ ✐ ✐ ✐

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 371 — #409 ✐ 12.6. Conversión automática de tipos Stringc s1("hello"), s2("there"); strcmp(s1, s2); // Standard C function strspn(s1, s2); // Any string function! } ///:~ Ahora cualquier función que acepte un argumento char* puede aceptar también un argumento Stringc porque el compilador sabe cómo crear un char* a partir de Stringc. 12.6.4. Las trampas de la conversión automática de tipos Dado que el compilador debe decidir cómo realizar una conversión de tipos, puede meterse en problemas si el programador no diseña las conversiones correctamente. Una situación obvia y simple sucede cuando una clase X que puede convertirse a sí misma en una clase Y con un operator Y(). Si la clase Y tiene un constructor que toma un argumento simple de tipo X, esto representa la conversión de tipos idéntica. El compilador ahora tiene dos formas de ir de X a Y, así que se generará una error de ambigüedad: //: C12:TypeConversionAmbiguity.cpp class Orange; // Class declaration class Apple { public: operator Orange() const; // Convert Apple to Orange }; class Orange { public: Orange(Apple); // Convert Apple to Orange }; void f(Orange) {} int main() { Apple a; //! f(a); // Error: ambiguous conversion } ///:~ La solución obvia a este problema es no hacerla. Simplemente proporcione una ruta única para la conversión automática de un tipo a otro. Un problema más difícil de eliminar sucede cuando proporciona conversiones automáticas a más de un tipo. Esto se llama a veces acomodamiento (FIXME): //: C12:TypeConversionFanout.cpp class Orange {}; class Pear {}; class Apple { public: operator Orange() const; operator Pear() const; 371 ✐ ✐ ✐ ✐

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 370 — #408<br />

✐<br />

Capítulo 12. Sobrecarga de operadores<br />

12.6.3. Ejemplo de conversión de tipos<br />

Un ejemplo <strong>en</strong> el que la conversión automática de tipos es extremadam<strong>en</strong>te útil<br />

es con cualquier clase que <strong>en</strong>capsule una cad<strong>en</strong>a de caracteres (<strong>en</strong> este caso, simplem<strong>en</strong>te<br />

implem<strong>en</strong>taremos la clase usando la clase estándar de <strong>C++</strong> string dado que<br />

es simple). Sin la conversión automática de tipos, si quiere usar todas las funciones<br />

exist<strong>en</strong>tes de string de la librería estándar de C, ti<strong>en</strong>e que crear un método para cada<br />

una, así:<br />

//: C12:Strings1.cpp<br />

// No auto type conversion<br />

#include "../require.h"<br />

#include <br />

#include <br />

#include <br />

using namespace std;<br />

class Stringc {<br />

string s;<br />

public:<br />

Stringc(const string& str = "") : s(str) {}<br />

int strcmp(const Stringc& S) const {<br />

return ::strcmp(s.c_str(), S.s.c_str());<br />

}<br />

// ... etc., for every function in string.h<br />

};<br />

int main() {<br />

Stringc s1("hello"), s2("there");<br />

s1.strcmp(s2);<br />

} ///:~<br />

Aquí, sólo se crea la función strcmp(), pero t<strong>en</strong>dría que crear las funciones correspondi<strong>en</strong>tes<br />

para cada una de que necesite. Afortunadam<strong>en</strong>te, puede<br />

proporcionar una conversión automática de tipos permiti<strong>en</strong>do el acceso a todas las<br />

funciones de .<br />

//: C12:Strings2.cpp<br />

// With auto type conversion<br />

#include "../require.h"<br />

#include <br />

#include <br />

#include <br />

using namespace std;<br />

class Stringc {<br />

string s;<br />

public:<br />

Stringc(const string& str = "") : s(str) {}<br />

operator const char*() const {<br />

return s.c_str();<br />

}<br />

};<br />

int main() {<br />

370<br />

✐<br />

✐<br />

✐<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!