#include <iostream>
#include <set>
using namespace std;
class StudentT {
public:
int id;
string name;
public:
StudentT(int _id, string _name) : id(_id), name(_name) {
}
int getId() {
return id;
}
string getName() {
return name;
}
};
inline bool operator< (StudentT s1, StudentT s2) {
return s1.getId() < s2.getId();
}
int main() {
set<StudentT> st;
StudentT s1(0, "Tom");
StudentT s2(1, "Tim");
st.insert(s1);
st.insert(s2);
set<StudentT> :: iterator itr;
for (itr = st.begin(); itr != st.end(); itr++) {
cout << itr->getId() << " " << itr->getName() << endl;
}
return 0;
}
In der Reihe:
cout << itr->getId() << " " << itr->getName() << endl;
Es gibt einen Fehler, dass:
../main.cpp:35: Fehler: Beim Übergeben von 'const StudentT' als 'this'-Argument von' int StudentT :: getId () 'werden Qualifizierer verworfen
../main.cpp:35: Fehler: Beim Übergeben von 'const StudentT' als 'this'-Argument von' std :: string StudentT :: getName () 'werden Qualifizierer verworfen
Was ist los mit diesem Code? Vielen Dank!
volatile
Antworten:
Die Objekte in
std::set
werden als gespeichertconst StudentT
. Wenn Sie also versuchen,getId()
mit demconst
Objekt aufzurufen, erkennt der Compiler ein Problem. Sie rufen hauptsächlich eine Nicht-Const-Member-Funktion für ein Const-Objekt auf, die nicht zulässig ist, da Nicht-Const-Member-Funktionen KEIN VERSPRECHEN machen, das Objekt nicht zu ändern. Der Compiler geht also von einer sicheren Annahme aus, diegetId()
möglicherweise versucht, das Objekt zu ändern, stellt jedoch gleichzeitig fest, dass das Objekt const ist. Daher sollte jeder Versuch, das const-Objekt zu ändern, ein Fehler sein. Daher generiert der Compiler eine Fehlermeldung.Die Lösung ist einfach: Machen Sie die Funktionen const wie folgt:
Dies ist notwendig , denn jetzt können Sie anrufen
getId()
undgetName()
auf const Objekte wie:Als Nebenbemerkung sollten Sie Folgendes implementieren
operator<
:Hinweis Parameter sind jetzt
const
Referenz.quelle
const StudentT & s1, const StudentT & s2
?const
die Funktion das Objekt nicht ändern muss, wirdconst
dies beim Kompilieren erzwungen .Mitgliedsfunktionen, die die Klasseninstanz nicht ändern, sollten wie folgt deklariert werden
const
:Immer wenn Sie "Qualifikationsmerkmale verwerfen" sehen, geht es um
const
odervolatile
.quelle
const
kommt, aber ich vermute, dass dasset
eine konstante Referenz vom Iterator zurückgibt, um zu verhindern, dass sich die Instanz ändert und dadurch die Menge ungültig macht.foo obj;
aufconst foo obj;
einmal und sehen Sie, was passiert. Oder geben Sie einenconst
Verweis auf afoo
.set
geändert werden, kann die Reihenfolge gestört werden und dann ist die Menge nicht mehr gültig. In amap
ist nur der Schlüsselconst
. In aset
ist das ganze Objekt wirklich der Schlüssel.f()
in meiner Antwort.Tatsächlich sagt der C ++ - Standard (dh C ++ 0x Entwurf ) (tnx an @Xeo & @Ben Voigt, um mich darauf hinzuweisen):
Die Implementierung von VC ++ 2008 Dinkumware ist also fehlerhaft.
Alte Antwort:
Sie haben diesen Fehler erhalten, weil in bestimmten Implementierungen der std lib
set::iterator
das gleiche ist wieset::const_iterator
.Zum Beispiel hat libstdc ++ (im Lieferumfang von g ++ enthalten) es (siehe hier für den gesamten Quellcode):
In den Dokumenten von SGI heißt es:
Andererseits kompiliert VC ++ 2008 Express Ihren Code, ohne sich darüber zu beschweren, dass Sie nicht konstante Methoden für
set::iterator
s aufrufen .quelle
Lassen Sie mich ein detaillierteres Beispiel geben. Zur folgenden Struktur:
Wie Sie oben sehen, gibt die IDE (CLion) Tipps
Non-const function 'getCount' is called on the const object
. In der Methodeadd
count
wird als const-Objekt deklariert, aber die MethodegetCount
ist keine const-Methode, dahercount.getCount()
können die Mitglieder in geändert werdencount
.Kompilierungsfehler wie folgt (Kernmeldung in meinem Compiler):
Um das oben genannte Problem zu lösen, können Sie:
uint32_t getCount(){...}
inuint32_t getCount() const {...}
. Alsocount.getCount()
werden die Mitglieder nicht geändertcount
.oder
uint32_t add(const Count& count){...}
zuuint32_t add(Count& count){...}
. Es ist alsocount
egal, ob Sie die Mitglieder wechseln.In Bezug auf Ihr Problem werden Objekte im std :: set als const StudentT gespeichert, aber die Methode
getId
undgetName
sind nicht const, daher geben Sie den obigen Fehler an.Sie können diese Frage auch sehen. Bedeutung von 'const' zuletzt in einer Funktionsdeklaration einer Klasse? für mehr Details.
quelle