2009-02-15 10 views
41

Sto avendo qualche problema con un particolare pezzo di codice, se qualcuno può illuminarmi su questo punto sarebbe molto apprezzato, ho isolato il problema verso il basso nel seguente esempio:Uno strano errore C++: test.cpp: 15: errore: passare 'const *' come 'questo' argomento di '*' scarta qualificatori

#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; 
} 

Quindi cosa potrebbe avere causa il seguente errore:

test.cpp: 15: errore: passare 'const testing' come 'this' argomento di 'int testing :: test()' scarta i qualificatori

Grazie mille!

risposta

64

Il problema sta chiamando un non const funzione test2.test() su un oggetto test2const da testing::test1.

testing::test1 ottiene test2 come parametro const testing &test2. Quindi entro testing::test1, test2const. Poi, nella prima riga della funzione:

test2.test() 

La funzione testing::test è chiamato test2. Tale funzione non è dichiarata con const alla fine della firma, quindi può modificare l'oggetto su cui è chiamato (il puntatore this è passato implicitamente ad esso) e anche se non lo fa, il compilatore lo assume. Lasciando che tu lo chiami lì, il compilatore ti permetterebbe di modificare una variabile const senza un cast esplicito, che C++ non dovrebbe permettere. Quindi per spiegare il messaggio di errore:

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

this riferisce all'oggetto la funzione membro (testing::test) opera su, e in questo caso non è const, perché testing::test non è stato dichiarato con const, e quindi la disallineamento viene rilevata quando si cerca di fare un const puntatore non (this) si riferiscono a un oggetto const (testing), ignorando la constqualificazione.

per risolvere questo, decidere se la funzione testing::test dovrebbe mai bisogno di modificare l'oggetto è chiamato (il modo in cui è scritto ora non, come tutto ciò che fa è return 1, tuttavia, che può cambiare, così è necessario pensare a quale sia la sua funzionalità prevista). Se è così, è ovvio che chiamare su un oggetto const non sia corretto, sebbene sia possibile utilizzare const_cast per chiedere al compilatore di sovrascriverlo, ma ciò è pericoloso. Se non dovrebbe, poi segnarlo const, in modo che possa essere chiamato const oggetti così:

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

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

La linea: test2.test()

sta chiamando una funzione non const, anche sebbene test2 sia un riferimento const. Questo è il problema. Puoi risolvere questo problema facendo test :: test una funzione const.

5

causa della definizione della funzione membro test1:

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

Si passa in un riferimento const per la test2 variabile.

Ciò significa che non è possibile modificare alcun membro di test2 e non è possibile chiamare alcuna funzione membro che non sia const o non sia statica.

Ecco come si può risolvere:

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

Il const extra alla fine dice al compilatore che non si prevede di modificare il contenuto dell'oggetto corrente (e se lo fate avrete una diversa errore di compilazione).

1

test :: test1 (const testing & test2) si aspetta che l'oggetto passato sia const e vi darà un errore se si modificano i valori delle sue variabili o se si accede a metodi che non sono definiti in modo esplicito come const.

Poiché il metodo di prova() non modifica i dati, prassi è quella di fissare const, come segue:

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

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

In alternativa, è sufficiente rimuovere la parola const nel definire gli argomenti per test1 (), e ti permetterà di accedere a tutti i metodi dell'oggetto passato a tuo piacimento.

-1

Per una soluzione rapida e sporca, provare a compilare con -fpermissive come spesso suggerito dal compilatore stesso (che è probabilmente ciò che fanno i compilatori VisualStudio, poiché gli utenti di Windows raramente segnalano questo problema).

Problemi correlati