2009-10-30 68 views
6

NOTA: Se que hay muchas preguntas que hablaban de eso, pero sigo siendo un principiante y no podía entender los ejemplos.const char * como un parámetro de la función en C++

tengo un prototipo de función que dice así:

int someFunction(const char * sm); 

Aquí, como usted sabe, const char * significa que esta función puede aceptar o const puntero-a-char no constante. He intentado algo así como que en el cuerpo de la función:

someMemberVar = sm; 

someMemberVar es sólo un puntero-a-char. El compilador me da un error diciéndome: no se puede convertir de const char * a char *.

Aquí, no pasé una constante, así que o sm o someMemberVar no son constantes. Entonces, ¿de qué constante está hablando el compilador?

+1

¿Cómo exactamente se declara 'someMemberVar', y cuál es el mensaje de error exacto que está recibiendo (el que proporciona no tiene ningún sentido, entonces sospecho que hay un error tipográfico allí). –

+0

He solucionado mi error. Se declara así: char * someMemberVar; –

+1

@ Alan es mayormente correcto. char * se puede convertir de forma segura en const char *, por lo que puedes pasar un char * a ese método como lo harías const char *. El compilador solo hará el reparto por ti. – Herms

Respuesta

10

Voy a tratar de poner en términos simples lo que otros dicen:

La función someFunction toma una cadena de sólo lectura (por simplicidad, aunque char * podrían utilizarse en otros innumerables casos). Si transfiere una cadena de solo lectura al someFunction o no, el código se trata como de solo lectura por el código que se ejecuta en el contexto de esta función. Dentro de esta función, por lo tanto, el compilador intentará evitar que escriba en esta cadena tanto como sea posible. Un puntero no constante es tal intento hacer caso omiso de la etiqueta de sólo lectura a la cuerda y el compilador, con razón y en voz alta le informa de tal desprecio por su sistema de tipos;)

Cuál es la diferencia entre: int algunaFuncion (const char * sm) const {...} y esto: int someFunction (const char * sm) {...}

La primera es una función que toma un parámetro de solo lectura. El segundo const escrito después de los paréntesis de cierre es válido solo para las funciones de miembro. No solo toma un parámetro de solo lectura, sino que también garantiza que no alterará el estado del objeto. Esto se conoce típicamente como const de nivel de diseño.

+0

Eso está bien. ¿Cuál es la diferencia entre: int algunaFunción (const char * sm) const {...} y esto: int someFunction (const char * sm) {...} –

+0

int someFunction (const char * sm) const {. ..} ¿const aquí significa que no alteraré ningún dato aquí, o se refiere al parámetro? –

+0

Ver mi respuesta actualizada. – dirkgently

10

No está del todo claro por su pregunta, y sospecho que el texto del error que da es realmente mal, y de hecho lee:

no se puede convertir de const char* a char*

Como dices que

someMemberVar es solo un puntero a char.

Esto tiene sentido. Tenga en cuenta que const char* es en realidad lo mismo que char const* - es decir, que es un puntero a un char const, no un puntero constante a char! Y no puede convertir un puntero a T const en un puntero a T, porque eso rompe la seguridad del tipo. Considere lo siguiente:

const char* a = "abc"; 
char* b = a; // what you're trying to do 
b[0] = 'x'; // if you could do it, you could change const data without casts 
+0

Gracias realmente ayudó. –

1

Si pasa un puntero no constante a someFunction, se convierte automáticamente a un puntero constante. Por lo tanto, no puede asignar sm a someMemberVar porque eso violaría la constness de sm. Puede declarar someMemberVar como const char* y su código funcionaría; sin embargo, no podría modificar lo que señalaba.

+0

const char * sm significa que puedo pasar un const o non-const, entonces ¿por qué C++ lo convierte automáticamente? Eso no tiene sentido para mí. –

+1

"const char * sm" significa "puntero a const char". Nada más. Eso es lo que sm tendrá en alguna función. Puede pasar un "char *" a alguna función porque se permite la conversión de no const a const. No se permite eliminar la constness, que es lo que intenta hacer cuando asigna sm a someMemberVar. – jamessan

+1

Dentro de la función, el puntero se convierte porque usted quiere que esté const dentro de esa función, usted lo declaró de esa manera. Es parte del contrato que la función realiza con sus llamadores. Si la función no quiere garantizar que la memoria apuntada por sm no cambie, no convierta el parámetro en const char *. –

0

const char * sm es un puntero a un carácter constante (o matriz). Cuando intenta asignar, someMemberVar, un puntero a char, que está tratando de apuntar a un conjunto de constantes caracteres. Esta es la causa del error.

3

const char* es un puntero a Char constante:


const char* ptr0; // ptr0 is mutable, *ptr0 is const 
char* const ptr1; // ptr1 is const, *ptr1 is mutable 
0

En su ejemplo SM es const char * modo algunaFuncion tiene un contrato con la persona que llama es que no va a modificar la memoria que los puntos a sm.

Pero si asigna sm a algunosMemberVar y someMemberVar no es const char *, entonces podrá modificar la memoria a la que sm apunta a través de algúnMemberVar y el compilador no le permite hacer eso.

1

En un comentario de una de las otras respuestas que dijo:

const char * sm significa que puedo pasar una constante o no constante, así que por qué C++ lo convierte de forma automática? Eso no tiene sentido para mí.

Entre su pregunta original y ese comentario, creo que no está entendiendo cómo trata el compilador los tipos.

Tiene la razón que un char * no const puede ser lanzado de manera segura a const char *. Sin embargo, su método toma explícitamente un const char *. Entonces, si bien puede pasar un char * en la función, el compilador simplemente arroja automáticamente el argumento al hacer la llamada a la función. El código real en la función no sabe si el argumento original era const o no. El compilador tiene que ir por la declaración real de la variable que está usando, no alguna variable anterior que tenía el mismo valor.

Si desea poder tratar las variables no const char * de manera diferente (asignándolas), entonces necesitará definir una función que tome variables no const char *.

Cuestiones relacionadas