Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO
✐ ✐ ✐ “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 ✐ ✐ ✐ ✐
- Page 357 and 358: ✐ ✐ ✐ “Volumen1” — 2012
- Page 359 and 360: ✐ ✐ ✐ “Volumen1” — 2012
- Page 361 and 362: ✐ ✐ ✐ “Volumen1” — 2012
- Page 363 and 364: ✐ ✐ ✐ “Volumen1” — 2012
- Page 365 and 366: ✐ ✐ ✐ “Volumen1” — 2012
- Page 367 and 368: ✐ ✐ ✐ “Volumen1” — 2012
- Page 369 and 370: ✐ ✐ ✐ “Volumen1” — 2012
- Page 371 and 372: ✐ ✐ ✐ “Volumen1” — 2012
- Page 373 and 374: ✐ ✐ ✐ “Volumen1” — 2012
- Page 375 and 376: ✐ ✐ ✐ “Volumen1” — 2012
- Page 377 and 378: ✐ ✐ ✐ “Volumen1” — 2012
- Page 379 and 380: ✐ ✐ ✐ “Volumen1” — 2012
- Page 381 and 382: ✐ ✐ ✐ “Volumen1” — 2012
- Page 383 and 384: ✐ ✐ ✐ “Volumen1” — 2012
- Page 385 and 386: ✐ ✐ ✐ “Volumen1” — 2012
- Page 387 and 388: ✐ ✐ ✐ “Volumen1” — 2012
- Page 389 and 390: ✐ ✐ ✐ “Volumen1” — 2012
- Page 391 and 392: ✐ ✐ ✐ “Volumen1” — 2012
- Page 393 and 394: ✐ ✐ ✐ “Volumen1” — 2012
- Page 395 and 396: ✐ ✐ ✐ “Volumen1” — 2012
- Page 397 and 398: ✐ ✐ ✐ “Volumen1” — 2012
- Page 399 and 400: ✐ ✐ ✐ “Volumen1” — 2012
- Page 401 and 402: ✐ ✐ ✐ “Volumen1” — 2012
- Page 403 and 404: ✐ ✐ ✐ “Volumen1” — 2012
- Page 405 and 406: ✐ ✐ ✐ “Volumen1” — 2012
- Page 407: ✐ ✐ ✐ “Volumen1” — 2012
- Page 411 and 412: ✐ ✐ ✐ “Volumen1” — 2012
- Page 413 and 414: ✐ ✐ ✐ “Volumen1” — 2012
- Page 415 and 416: ✐ ✐ ✐ “Volumen1” — 2012
- Page 417 and 418: ✐ ✐ ✐ “Volumen1” — 2012
- Page 419 and 420: ✐ ✐ ✐ “Volumen1” — 2012
- Page 421 and 422: ✐ ✐ ✐ “Volumen1” — 2012
- Page 423 and 424: ✐ ✐ ✐ “Volumen1” — 2012
- Page 425 and 426: ✐ ✐ ✐ “Volumen1” — 2012
- Page 427 and 428: ✐ ✐ ✐ “Volumen1” — 2012
- Page 429 and 430: ✐ ✐ ✐ “Volumen1” — 2012
- Page 431 and 432: ✐ ✐ ✐ “Volumen1” — 2012
- Page 433 and 434: ✐ ✐ ✐ “Volumen1” — 2012
- Page 435 and 436: ✐ ✐ ✐ “Volumen1” — 2012
- Page 437 and 438: ✐ ✐ ✐ “Volumen1” — 2012
- Page 439 and 440: ✐ ✐ ✐ “Volumen1” — 2012
- Page 441 and 442: ✐ ✐ ✐ “Volumen1” — 2012
- Page 443 and 444: ✐ ✐ ✐ “Volumen1” — 2012
- Page 445 and 446: ✐ ✐ ✐ “Volumen1” — 2012
- Page 447 and 448: ✐ ✐ ✐ “Volumen1” — 2012
- Page 449 and 450: ✐ ✐ ✐ “Volumen1” — 2012
- Page 451 and 452: ✐ ✐ ✐ “Volumen1” — 2012
- Page 453 and 454: ✐ ✐ ✐ “Volumen1” — 2012
- Page 455 and 456: ✐ ✐ ✐ “Volumen1” — 2012
- Page 457 and 458: ✐ ✐ ✐ “Volumen1” — 2012
✐<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 />
✐