Frage const Vektor impliziert konstante Elemente?


Tut const vector<A> bedeuten, dass seine Elemente sind constauch?

Im folgenden Code

v[0].set (1234);  im void g ( const vector<A> & v ) erzeugt den Compilerfehler

const.cpp: 28: 3: error: Mitgliedsfunktion 'set' nicht durchführbar: 'this'   Argument hat         Geben Sie 'const value_type' (aka 'const A') ein, aber die Funktion ist nicht const

Warum?

Aber (*v[0]).set(1234); im void h ( const vector<A *> & v ) ist in Ordnung für den Compiler.

Was ist der Unterschied zwischen den Versionen?

// ...........................................................
class A {
private:
  int a;
public:
  A (int a_) : a (a_) { }
  int get () const { return a; }
  void set (int a_) { a = a_; }
};

// ...........................................................
void g ( const vector<A> & v ) {
  cout << v[0].get();
  v[0].set (1234); 
} // ()

// ...........................................................
void h ( const vector<A *> & v ) {
  cout << (*v[0]).get();
  (*v[0]).set(1234);
} // ()

22
2017-11-21 16:09


Ursprung


Antworten:


Die erste Version

v[0].set (1234); 

kompiliert nicht, weil es versucht, das erste Element des Vektors zu ändern, das durch Referenz zurückgegeben wird. Der Compiler denkt, dass es eine Änderung ist, weil set(int) ist nicht markiert const.

Die zweite Version hingegen nur liest aus dem Vektor

(*v[0]).set(1234);

und Anrufe set über das Ergebnis der Dereferenzierung eines konstanten Verweises auf einen Zeiger, den es zurückbekommt.

Wenn du anrufst v[0] auf einen const Vektor, erhalten Sie zurück ein const Bezug auf A. Wenn der Elementtyp ein Zeiger ist, ruft er auf set darauf ist es in Ordnung. Sie könnten das zweite Beispiel zu ändern

v[0]->set(1234);

und bekomme das gleiche Ergebnis wie zuvor. Dies liegt daran, dass Sie einen Verweis auf einen Zeiger erhalten, der konstant ist, aber das Element, auf das der Zeiger zeigt, ist nicht konstant.


9
2017-11-21 16:14



Ja ein const vector bietet Zugriff auf seine Elemente als ob sie waren constdas heißt, es gibt nur dir const Verweise. In Ihrer zweiten Funktion sind es nicht die Objekte vom Typ A das sind const, aber Zeiger zu ihnen. Ein Zeiger ist const bedeutet nicht, dass das Objekt, auf das der Zeiger zeigt, ist const. Verwenden Sie den Typ, um einen Zeiger auf const zu deklarieren A const *.


14
2017-11-21 16:13



Ein const-Objekt kann also nur const-Methoden aufrufen. Das ist:

class V {
  public:
    void foo() { ... }        // Can't be called
    void bar() const  { ... } // Can be called
};

Schauen wir uns also ein Vektoroperator []:

reference       operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;

Wenn also das Vektorobjekt const ist, gibt es a zurück const_reference.

Über: (*v[0]).set(1234);

Lasst uns das durchbrechen:

A * const & ptr = v[0];
A & val = *ptr;
val.set(1234);

Beachten Sie, dass Sie einen konstanten Zeiger auf variable Daten haben. Sie können also nicht ändern, worauf gezeigt wird, aber Sie können den Wert ändern, auf den der Zeiger zeigt.


7
2017-11-21 16:16