const_iterator



  • Hallo,
    wenn ich eine eigene Klasse mit iterator und const_iterator dann brauche ich ja auch 2x die methoden begin und end. Aber wenn ich dann im Programm eingebe Klasse.begin(). Woher weiß der Complier dann, ob er das const begin oder das normale begin nehmen soll?



  • #include <iostream>
    
    class Foo
    {
    public:
      void hallo()       {std::cout << "non-const!\n";}
      void hallo() const {std::cout << "    CONST!\n";}
      //           ^^^^^
      //  für den this-Parameter
    };
    
    int main() {
      Foo f;
      Foo      * p1 = &f;
      Foo const* p2 = &f;
      p1->hallo();
      p2->hallo();
    }
    

    Ausprobieren: HIER



  • Foo const* p2 = &f;
    

    ist ein Zeiger auf ein konstantes Objekt oder?



  • Der Anfänger! schrieb:

    Foo const* p2 = &f;
    

    ist ein Zeiger auf ein konstantes Objekt oder?

    Viele würden das bejahen. Strenggenommen ist das Objekt, bezeichnet durch f, nicht "konstant". Aber das Objekt hinter f lässt sich eben über p2 nicht verändern, weil nur const-Methoden über p2 aufgerufen werden können und jeder Elementzufriff über p2 auch automatisch const-qualifiziert ist. Man sagt trotzdem "p2 ist ein Zeiger auf ein konstantes Foo" wobei damit gemaint ist, dass Objekt nicht unbedingt konstant ist, nur über diesen Zeiger eben nicht verändert werden kann.



  • krümelkacker schrieb:

    [...]

    Du sagst der Pointer zeigt nicht auf ein konstantes Objekt, weil das Objekt, dessen Adresse genommen wurde nicht konstant war. Mit der Argumentation kann man dann aber auch weiter gehen und erklären, dass eigentlich so ziemlich alles nicht-konstant ist, denn man kann auf alles was auf dem Heap und Stack liegt ein const_cast bügeln um es zu verändern. Und dann geht man noch weiter und sagt dass ja eh eigentlich alles im Hauptspeicher ist und es höchstwahrscheinlich irgendwelche abstrusen Möglichkeiten geben wird, mit Betriebssystemmitteln alles was da rumliegt zu verändern. Nichts ist also const.
    Rein sprachlich ist ein Pointer to const ein Pointer auf ein Konstantes Objekt, Punkt. Man kann darüber das Obejekt nicht verändern, mutable member ausgenommen. Selbst ein const_cast ändert da nichts dran, der liefert nur einen weiteren Pointer (mit dem selben Wert), aber auf ein nichtkonstantes Objekt.



  • Ich wollte mit meiner Erklärung eigentlich mögliche Missverständnisse vermeiden.

    pumuckl>> denn man kann auf alles was auf dem Heap und Stack liegt ein const_cast bügeln um es zu verändern.

    Nein, kann man nicht:

    int main() {
      const int blupp = 1;
      const_cast<int&>(blupp) = 0; // undefiniertes Verhalten
      return blupp;
    }
    

    pumuckl>> Rein sprachlich ist ein Pointer to const ein Pointer auf ein Konstantes Objekt

    Dass das so sprachlich benutzt wird, bestreite ich nicht. Ich wollte nur erklären, dass es sich dabei nicht wirklich um ein "konstantes Objekt" handeln muss, sondern dass das const beim Zeiger eher so etwas wie eine Zugriffsbeschränkung ist.



  • krümelkacker schrieb:

    Nein, kann man nicht:

    int main() {
      const int blupp = 1;
      const_cast<int&>(blupp) = 0; // undefiniertes Verhalten
      return blupp;
    }
    

    Das ist deswegen undefiniert weil der Compiler die Konstante wegoptimieren darf, so dass es dann nichts mehr gibt was auf dem stack liegen würde. Grundsätzlich kann man aber solang etwas tatsächlich auf dem Stack existiert, mit entsprechenden Hacks da lustig drauf rumschreiben, auch wenns an allen Regeln der Sprache und des guten Geschmacks vorbeigeht.



  • pumuckl schrieb:

    Das ist deswegen undefiniert weil [...]

    Es ist undefiniert. Das warum und wieso tut hier gar nichts zur Sache.

    pumuckl schrieb:

    Nichts ist also const.

    🙄


Anmelden zum Antworten