2009-02-15 11 views
41

Tengo algunos problemas con un código en particular, si alguien me puede aclarar en esta materia que sería muy apreciada, he aislado el problema en el siguiente ejemplo:Un error extraño de C++: test.cpp: 15: error: pasar 'const *' como 'este' argumento de '*' descarta los calificadores

#include <iostream> 

using namespace std; 

class testing{ 
    int test(); 
    int test1(const testing& test2); 
}; 

int testing::test(){ 
    return 1; 
} 

int testing::test1(const testing& test2){ 
    test2.test(); 
    return 1; 
} 

Así que lo que podría tener una causa del error siguiente:

test.cpp: 15: error: pasar 'const testing' como 'este' argumento de 'int testing :: test()' descarta calificadores

¡Muchas gracias!

Respuesta

64

El problema está llamando a una función no consttest2.test() en un objeto test2const de testing::test1.

testing::test1 obtiene test2 como parámetro const testing &test2. Entonces dentro de testing::test1, test2const. Luego, en la primera línea de la función:

test2.test() 

La función se llama testing::test en test2. Esa función no se declara con const en el extremo de la firma, por lo que puede modificar el objeto al que se llama (el puntero this se le pasó implícitamente), y aunque no lo hace, el compilador asume que sí. Al permitir que lo invoque allí, el compilador le permite modificar una variable const sin un molde explícito, que C++ no debe permitir. Por lo tanto, para explicar el mensaje de error:

test.cpp:15: error: passing ‘const testing’ as ‘this’ argument of ‘int testing::test()’ discards qualifiers 

this se refiere al objeto de la función miembro (testing::test) opera en, y en este caso no es const, porque testing::test no fue declarado con const, y por lo tanto la desajuste se detecta cuando se trata de hacer una const puntero no (this) se refieren a un objeto const (testing), ignorando el calificador const.

para resolver este, decidir si la función testing::test debe necesitar modificar el objeto al que se llama en (la forma en que se escribe ahora no, ya que lo único que hace es return 1, sin embargo, que puede cambiar, por lo necesitas pensar en cuál es su funcionalidad prevista). Si es así, obviamente llamarlo a un objeto const es malo, aunque puede usar const_cast para solicitar al compilador que lo anule, pero esto es peligroso. Si no debe, a continuación, marcarlo const, por lo que se puede llamar en const objetos así:

class testing{ 
    int test1() const; 
    // ... 
} 

int testing::test() const { 
    // ... 
} 
2

La línea: test2.test()

está llamando a una función no constante, incluso aunque test2 es una referencia constante. Ese es el problema. Puede solucionar esto haciendo testing :: test a const function.

5

Debido a la definición de la función miembro test1:

int testing::test1(const testing& test2){ 
    test2.test(); 
    return 1; 
} 

Usted está de paso en una referencia constante de la test2 variable.

Eso significa que no puede modificar ningún miembro de test2 y no puede llamar a ninguna función miembro que no sea const o no sea estática.

Aquí es cómo se puede arreglar:

int testing::test() const { 
    return 1; 
} 

La const extra al final le dice al compilador que no está pensando en modificar el contenido del objeto actual (y si lo hace obtendrá una diferente error de compilación).

1

testing :: test1 (const testing & test2) espera que el objeto pasado sea const, y le dará un error si modifica los valores de sus variables, o accede a cualquier método del mismo que no esté explícitamente definido como const.

Dado que el método test() en realidad no cambia los datos, la mejor práctica es establecer que const, de la siguiente manera:

class testing{ 
    int test() const; 
    int test1(const testing& test2); 
}; 

int testing::test() const { 
    return 1; 
} 

Como alternativa, sólo eliminar la palabra const en la definición de los argumentos a favor de test1 (), y le permitirá acceder a cualquiera de los métodos del objeto pasado a su gusto.

-1

Para una solución rápida y sucia, intente compilar con -fpermissive tantas veces sugerido por el propio compilador (que es probablemente lo que hacen los compiladores de VisualStudio, ya que los usuarios de Windows rara vez informan sobre este problema).

Cuestiones relacionadas