Operator[] Überladen: Aufgabe von const



  • Moin,

    Ich habe eine Klasse in der ich den []Operator überlade um mir ein Element von einem Vektor ausgeben zu lassen.
    Die Überladung sieht wie folgt aus:

    T const& operator[] (size_t i) const
    {
    return a[i];
    }

    T ist ein template
    a ist ein vector der Teil der Klasse ist.

    Jetzt habe ich ein Verständnisproblem und zwar wofür brauche ich das const am Ende der ersten Zeile?
    Bzw was bewirkt das erste const und was das zweite?
    Ich konnte in meinem Programm feststellen wenn ich beide const weglasse
    das es möglich ist ein Element vom Vektor zu überschreiben in dem ich in der main z.B. schreibe p[0]=3 (p ist ein erzeugtes Objekt). Wenn ich das erste const wieder hinzufüge dann geht das nicht mehr. Aber was bewirkt das const am Ende?
    Zu welchen Problemen kann es führen wenn ich es weglasse?
    Bitte habt Nachsicht mit mir, ich bin Anfänger.
    Danke für eure Hilfe!

    Gruss



  • Der Rückgabetyp deiners operator[]() ist in deiner obigen Version T const & , also - rückwärts lesen - eine Referenz auf ein konstantes T . Du kannst über die zurückgegebene Referenz nichts an den Innereien einer Klasseninstanz ändern.

    Das const am Ende der Funktionssignatur ist ein Versprechen: Das Versprechen, daß die Funktion die Instanz nicht verändern wird. Dieses Versprechen musst du abgeben, damit du deinen operator[]() auf const -qualifizierte Instanzen deiner Klasse aufrufen darfst:

    #include <vector>
    #include <iostream>
    
    template< typename T >
    class Foo
    {
    	public:
    		typedef T          value_type;
    		typedef T &        reference;
    		typedef T const &  const_reference;
    		typedef T *        pointer;
    		typedef T const *  const_pointer;
    
    		typedef std::vector< value_type >      container;
    		typedef typename container::size_type  size_type;
    
    	private:
    		container data;
    
    	public:
    		Foo( std::initializer_list< value_type > && il ) : data( il ) {}
    
    		reference operator[]( size_type index )
    		{
    			std::cout << "operator[]()\n";
    			return data.at( index );
    		}
    
    		const_reference operator[]( size_type index ) const
    		{
    			std::cout << "operator[]() - const qualifiziert\n";
    			return data.at( index );
    		}
    };
    
    int main()
    {
    	Foo< int > foo{ 1, 2, 3 };
    	std::cout << foo[ 1 ] << '\n';
    	foo[ 1 ] = 42;  // ok
    	std::cout << foo[ 1 ] << '\n';
    
    	Foo< int > const foo_const{ 1, 2, 3 };
    	std::cout << foo_const[ 1 ] << '\n';
    	// foo_const[ 1 ] = 42;  // compiler error
    }
    


  • Vielen Dank für deine Hilfe 😉

    Eine letzte Sache noch

    D.h. wenn ich kein const am Anfang habe, sprich wenn meine referenz auf den Rückgabewert der Funktion nicht const ist, dann ist es möglich den Rückgabewert von aussen zu ändern oder?



  • Da musst du leider auf die Antwort eines Qualifizierten warten. // 🙄 vergessen.


  • Mod

    Jazz1234 schrieb:

    D.h. wenn ich kein const am Anfang habe, sprich wenn meine referenz auf den Rückgabewert der Funktion nicht const ist, dann ist es möglich den Rückgabewert von aussen zu ändern oder?

    Ja.


Anmelden zum Antworten