[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 fromvoid 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 from void 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 memberconst
    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 operator

    1. 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 mit

    klassenlist[0].zahl=4711;
    

    trotzdem schlechte karten.

    Klasse a(4711,"");
    klassenlist[0]=a;
    

    würde funktionieren.
    Kurt


Anmelden zum Antworten