[STL] const-Member-Behandlung mit list und vector
-
Hallo,
ich habe eine Verständnisfrage zur Behandlung von Klassen mit const-Member, im Falle von list und vector. Folgender Code wird von gcc ohne weiteres akzeptiert:
#include <vector> #include <list> #include <iostream> using namespace std; class Klasse { private: const int zahl; const string zeichenkette; public: Klasse(const int zahl, const string zeichenkette): zahl(zahl), zeichenkette(zeichenkette) { cout<<"Konstruktor"<<endl; } Klasse(const Klasse& klasse): zahl(klasse.zahl), zeichenkette(klasse.zeichenkette) { cout<<"Kopiekonstruktor"<<endl; } ~Klasse() { cout<<"Destruktor von Objekt "<<zeichenkette<<endl; } }; int main() { list<Klasse> klassenliste; // kein Problem mit list, aber mit vector Klasse objekt(1, "Objekt"); klassenliste.push_back(objekt); }
Wenn ich aber in der kommentierten Zeile list zu vector änder, gibt es das Problem mit konstanten Member aus der Klasse:
/usr/include/c++/3.3/bits/vector.tcc: In member function
Klasse& Klasse::operator=(const Klasse&)': /usr/include/c++/3.3/bits/vector.tcc:230: instantiated from
void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<_Tp*, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = Klasse, _Alloc = std::allocator<Klasse>]'
/usr/include/c++/3.3/bits/stl_vector.h:603: instantiated fromvoid std::vector<\_Tp, \_Alloc>::push\_back(const \_Tp&) [with \_Tp = Klasse, _Alloc = std::allocator<Klasse>]' test1.cpp:39: instantiated from here /usr/include/c++/3.3/bits/vector.tcc:230: error: non-static const member
const
int Klasse::zahl', can't use default assignment operator
/usr/include/c++/3.3/bits/vector.tcc:230: error: non-static const member `const
std::string Klasse::zeichenkette', can't use default assignment operator1. Wieso ist das so? Muss da für vector noch eine Operator-Überladung hin?
2. Dann noch eine Frage zu dem Kopiekonstruktor. Habe des öfteren gelesen, dass in Verbindung von Objekten und Container-Elementen, extra ein Kopiekonstruktor angelegt werden sollte. Ist das in meinem Fall unbedingt so notwendig? Wird nicht automatisch ein Standard-Kopiekonstruktor angewendet?
Vielen Dank
-
für vektor ist der [] operator definiert.
Der compiler kann aber keinen default = operator erstellen wegen deiner const members. für list ist operator [] nicht definiert daher wird auch kein operator = gebraucht .
Kurt
-
Zu 2:
In deinem Fall brauchst du keinen eigenen Copy-Ctor, da die Default-Variante bereits das richtige tut.Wird nicht automatisch ein Standard-Kopiekonstruktor angewendet?
Der Punkt ist, dass die Semantik des automatisch generierten Copy-Ctors nicht für alle Klassen passend ist. Wenn deine Klasse z.B. Pointer-Member benutzt musst du dich entscheiden, was kopieren bedeuten soll. Deep-Copy? Shallow-Copy? Und was ist mit Ownership?
-
Vielen Dank für Eure Antworten.
Habe ich das richtig verstanden, dass im Falle eines indizierten Zugriffs auch entsprechend eine Zuweisung erfolgen könnte:klassenlist[0].zahl=4711;
Und bei list erfolgt sowas eher über einen Iterator.
Korrekt?!
-
jo aber eher
klassenlist[0]=4711;
kurt
-
Hmmm..., jetzt bin ich'n bischen durcheinander?
Mit klassenlist[0] greife ich doch auf ein objekt der Klasse 'Klasse' zu. Um eine Wertzuweisung für einen nichtkonstanten Member vornehmen zu können, muss ich den doch erstmal angeben, oder?!
-
Du hast recht. Bin heute nicht gut drauf.
da klasse.zahl aber als const declariert ist hast du mitklassenlist[0].zahl=4711;
trotzdem schlechte karten.
Klasse a(4711,""); klassenlist[0]=a;
würde funktionieren.
Kurt