2010-08-06 28 views
10

tengo una clase como ésta:¿Por qué mi sobrecargado constructor de C++ no se llama?

class Test{ 
public: 
    Test(string value); 
    Test(bool value); 

}; 

Si creo un objeto como éste:

Test test("Just a test..."); 

El constructor bool se llama!

¿Alguien sabe por qué?

Gracias

+0

C++ no tiene métodos, por cierto, sólo funciones miembro. Además, estás hablando de constructores aquí. –

+0

¡Guau, hoy encontré exactamente el mismo problema! – Milan

Respuesta

18

El tipo de "Just a test..." es const char *, que se pueden transformar implícitamente a cualquiera bool o std::string. Como std::string no es un tipo incorporado, el const char * s se convierte en bool. Usted puede evitar que al convertir explícitamente el const char * a un std::string:

Test test(std::string("Just a test...")); 
+2

La solución es correcta, pero la explicación no es completamente correcta. Usted * puede * implícitamente convertir de 'const char *' a 'std :: string' (a través de uno de los constructores' std :: string'). Es solo que se prefiere la conversión bool. –

+0

Haré ese cambio, ¡gracias! –

+1

"Solo una prueba ..." no es char *. En C++ es char const []. –

4

El tipo de "Just a test..." es const char*. Hay una conversión incorporada de punteros a bool que se prefiere sobre la conversión no incorporada de const char* a std::string.

La razón por la que se prefiere la conversión de bool es porque std::string, aunque forma parte de la biblioteca estándar, no es un tipo integrado como enteros, punteros y booleanos. Actúa como cualquier otra clase, por lo que sus constructores de conversión se consideran solo después de las conversiones a los tipos incorporados.

8

Esto es una molestia bien conocida de C++.

Su cadena literal tiene el tipo de chat const []. Tienes dos constructores, secuencias de conversión de const char [] para probar el siguiente aspecto:

1) const char [] -> const char * -> bool

2) const char [] -> char const * -> std :: string

1) es una conversión estándar incorporada, mientras que 2) es una conversión definida por el usuario. Las conversiones integradas tienen prioridad sobre las conversiones definidas por el usuario, por lo tanto, su cadena literal se convierte más fácilmente en bool que en std :: string.

0

Una forma es crear una variable de tipo std :: string y pasar la variable en:

std::string test = "TEST"; 
A a(test); 

De esta manera el tipo se define explícitamente como std::string no será por defecto el constructor que acepta bool

3

Una forma de eludir este problema es proporcionar otro constructor tomando un const char * y luego convirtiendo explícitamente a std :: string.

1

Cuando tiene un constructor (especialmente múltiples constructores) que toma solo un argumento, puede ser adecuado declararlo "explícito" para evitar este tipo de sorpresas. Esto obliga al usuario de la clase a asegurarse de que le da el tipo correcto al constructor que desea utilizar y evita que estas conversiones de tipo implícito se realicen detrás de los usuarios y ocultando errores difíciles de encontrar.

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15&rll=1

En C++ 0x, esto se ha extendido a los operadores de conversión para evitar que el mismo problema

http://www2.research.att.com/~bs/C++0xFAQ.html#explicit-convertion

Cuestiones relacionadas