2009-03-26 9 views
11

Estoy tratando de usar un tipo de devolución de const MyClass * const. Sin embargo, recibo una advertencia:¿Por qué mi tipo de devolución no tiene sentido?

Advertencia: # 815-D: el calificador de tipo en el tipo de devolución no tiene sentido.

¿Este no es un tipo válido? Quiero un puntero que no se puede cambiar, y quiero que lo que señala no se modifique tampoco.

+0

¿Qué indicadores de compilación y compilación estás usando? – Trent

+1

RVCT 3.1 y no sé qué banderas las entrañas de las banderas del sistema de compilación están ocultas de nosotros simples mortales – Dynite

Respuesta

22

El puntero en sí tiene tipo de valor, por lo que no tiene sentido para que sea const. Lo que hace la función de llamador con el valor devuelto no puede ser restringido por la función llamada. Esto es similar a tratar de definir algo como:

const int getInt(); 

getInt(), en este caso, simplemente devuelve un valor entero (no una referencia). Va a un registro, luego la función de la persona que llama lo recibe y hace lo que quiera con él.

+0

Entonces, básicamente, ¿solo se pueden definir los tipos de retorno const con referencias? – Dynite

+0

Sí (por referencia, que significa tanto referencias como objetos puntiagudos). El puntero en sí no puede ser const, es solo un valor copiado. – Juliano

+0

El puntero no se puede const cuando se devuelve desde una función, pero puede tener un puntero de const en un sitio de llamada (ver mi respuesta a continuación). Esto evita que alguien reasigne inadvertidamente a un puntero cuando realmente está usando el puntero. –

0

el calificador const no significa nada porque estás devolviendo un puntero

4

¿Por qué te importa si cambias el puntero? Hacer esto es como decir:

const int f() { 
    ... 
} 

El valor devuelto por f() es una copia - cambiante no cambia nada, por lo que no es el punto nom en lo que es const.

+0

Estaba pensando que no quiero que la gente haga algo como puntero ++, porque el tamaño de cada objeto individual no es el mismo. – Dynite

+3

@Dynite, esto es como darle a las personas su dirección, por ejemplo, 80, Main Street, y luego preguntarse qué sucederá si tocan el timbre en 81, Main Street. –

+0

@Dynite - como señala Daniel, pueden hacerlo de todos modos, por lo que no obtienes nada excepto un ejercicio de teclado adicional –

4

Una forma simple de asegurarse de que está definiendo el tipo de devolución que desea es siempre agregar modificadores en el lado derecho (en lugar de izquierdo) del tipo original.

MyClass     // MyClass object 
MyClass const   // MyClass object which can't be modified 
MyClass const &   // reference of an unmodifiable MyClass object 
MyClass const *   // pointer to an unmodifiable MyClass object 
MyClass const * const // unmodifiable pointer to an unmodifiable MyClass object 
MyClass const * const & // reference of an unmodifiable pointer to an unmodifiable MyClass object 

que debe ayudar a asegurarse de que sus tipos de retorno no tienen sentido de nuevo :)

+1

De la pregunta: "puntero que no se puede cambiar, y ... lo que apunta a no ser cambiado tampoco". Declaró el tipo de devolución correctamente en función de sus intenciones. – Trent

+0

Sí, lo hizo. Y solo recibió una advertencia del compilador sobre el significado de estas cosas en el valor de retorno. – dragonfly

5

Estoy de acuerdo con la respuesta de Juliano, desea que el constness del puntero sea en el lugar de llamada.

Una mejor manera de hacer lo que busca es que su función devuelve una referencia constante al objeto:

const MyClass& getMyClass() 
{ 
    return myClass; 
} 

Por referencias definición no se puede modificar, por lo que sería mejor .

Por supuesto, esto no funcionará si su función está intentando crear un objeto MyClass. En ese caso, puede mover el const extra al sitio de llamadas.

// function definition 
const MyClass* createMyClass() 
{ 
    return new MyClass("I Love C++"); 
} 

// use of a const pointer to a MyClass which is const 
const MyClass* const myClassInstance = creatMyClass(); 
0

¿Por qué devolver un valor const? Considere lo siguiente (y disculpen los nombres de las variables sin imaginación):

struct A { int a; }; 

A operator+(const A& a1, const A& a2) 
{ 
    A a3 = { a1.a + a2.a }; 
    return a3; 
} 

Dado que la declaración de operator+, puedo hacer lo siguiente:

A a = {2}, b = {3}, c = {4}, d = ((a+b) = c); 

Así es, me acaba de asignar a la temporal A que fue devuelto por operator+. El valor resultante de d.a es 4, no 5.Si se cambia el tipo de devolución de operator+ a const A se evita esta asignación, lo que provoca que la expresión (a+b) = c genere un error de compilación.

Si trato de asignar a un puntero o entero devuelto por una función, mi compilador (MSVC) genera un error de "operando izquierdo debe ser l-value", que parece consistente con el compilador ARM que le dice que la const el puntero no tiene sentido; el puntero no se puede asignar de todos modos. Pero para clases/estructuras, aparentemente está bien asignar valores de retorno no const.

Cuestiones relacionadas