Zugriff auf Vektorelemente einer Klasse



  • Hallo,

    ich bin noch ziemlicher Anfänger und habe dementsprechend eine ziemliche Anfängerfrage:

    Mein Programm besteht aus einer Main-Funktion und einer Klasse. In dieser Klasse definiere ich mir einen Konstruktor, welcher mir ein Objekt initialisiert, welches im Wesentlichen einfach gleich einem übergebenen Vektor ist

    (ich erschaffe also sozusagen ein Objekt vom Typ meiner Klasse, welches einfach nur charakterisiert wird durch einen Vektor, der gleich dem übergebenen Vektor ist.)

    Angenommen dieses Objekt würde nun durch irgendeine Funktion verändert werden (also die Elemente des Vektors würden sich ändern).

    Ich möchte nun auf das beispielsweise zweite Element dieses Vektors zugreifen, der sich hinter meinem Objekt verbirgt.

    Meine Frage: Wie mache ich das? Ich habe alles mögliche ausprobiert, aber nichts klappt. Bei einem Vektor wäre es einfach der []-Operator, welcher natürlich aber für Objekte meiner Klasse nicht definiert ist. Auch irgendwie mit Pointern was zu bewerkstelligen habe ich nicht geschafft.

    Vielen Dank im Voraus


  • Mod

    Deine Klasse muss eben irgendeine Funktion anbieten, die Zugriff auf das gewünschte Attribut erlaubt. Dass es sich um einen vector handelt, ändert im Prinzip nichts, außer dass man möglicherweise gleich eine Funktion anbieten kann, die einen Index als Parameter übernimmt, anstatt den ganzen vector zurück zu geben:

    class Foo
    {
      vector<Datentyp> data;
    public:
      Datentyp& get_data(size_t index) { return data[index]; }
      const Datentyp& get_data(size_t index) const { return data[index]; }
    };
    
    // Oder mit Operatorüberladung:
    class Bar
    {
      vector<Datentyp> data;
    public:
      Datentyp& operator[](size_t index) { return data[index]; }
      const Datentyp& operator[](size_t index) const { return data[index]; }
    };
    


  • Hallo, danke schonmal, damit habe ich es jetzt hinbekommen.

    Ich hätte aber noch ein paar Fragen:

    Wieso schreibst du in der zweiten Variante hinter "Datentyp" ein "&"? Wenn ich dieses weglasse, so funktioniert mein Programm dennoch, und ich kann mir gerade auch nicht vorstellen, was dieses & in dieser Situation bewirkt bzw wodurch sich die beiden Varianten unterscheiden.



  • Ich habe gerade auch diesen Operator für meine Klasse "name" geschrieben, der sozusagen der "Skalaren Multiplikation" von einem Vektor mit einer natürlichen Zahl entsprechen soll:

    name operator*(int k)
    {
    for (int i=1; i<=x.size(); ++i){
    x[i-1]=k*x[i];
    }
    return name(&x);
    }

    (falls noch relevant, hier der Konstruktor:

    name (vector <int> *a): x(*a)
    {
    int n = (*a).size();
    x.resize(n);
    int i=1;
    auto it = (*a).begin();
    while (i<=n){
    x[i-1]=*it;
    it++;
    i++;

    }} )

    Jedenfalls kriege ich hier zB. irgendeine Fehlermeldung, falls ich beim Operator * name& als Rückgabewert schreibe. Wo liegt der Unterschied zum vorherigen Operator []?



  • clerner schrieb:

    Hallo, danke schonmal, damit habe ich es jetzt hinbekommen.

    Ich hätte aber noch ein paar Fragen:

    Wieso schreibst du in der zweiten Variante hinter "Datentyp" ein "&"? Wenn ich dieses weglasse, so funktioniert mein Programm dennoch, und ich kann mir gerade auch nicht vorstellen, was dieses & in dieser Situation bewirkt bzw wodurch sich die beiden Varianten unterscheiden.

    Wenn dein Datentyp jedoch teuer zu kopieren ist, dann spürst du das. Wenn er gar nicht kopierbar ist, dann kompiliert dein Programm nicht.



  • Skym0sh0 schrieb:

    clerner schrieb:

    Hallo, danke schonmal, damit habe ich es jetzt hinbekommen.

    Ich hätte aber noch ein paar Fragen:

    Wieso schreibst du in der zweiten Variante hinter "Datentyp" ein "&"? Wenn ich dieses weglasse, so funktioniert mein Programm dennoch, und ich kann mir gerade auch nicht vorstellen, was dieses & in dieser Situation bewirkt bzw wodurch sich die beiden Varianten unterscheiden.

    Wenn dein Datentyp jedoch teuer zu kopieren ist, dann spürst du das. Wenn er gar nicht kopierbar ist, dann kompiliert dein Programm nicht.

    Sorry, ich verstehe nicht was du meinst. Wie gesagt, ich bin ein Anfänger, "teuer zu kopieren" sagt mir gar nichts.



  • Du musst so viele Daten kopieren, dass die Performance spürbar zurück geht. Z.B. ein vector mit 1.000.000 floats, oder double, oder sonst was. Das zu kopieren will man vermeiden. Du merkst sowas auch, wenn du Gigabyte große ordner auf deiner Festplatte verschieben willst. Da wartet man ganz schön...



  • * kopieren meinte ich



  • Und inwiefern beantwortet das meine Frage? Ich wollte wissen, was dieses & bewirkt. Ich habe keine Ahnung, was es in diesem Zusammenhang dort zu suchen hat. Und dies hat mir nach wie vor niemand erklärt.



  • Das & kennzeichnet hier eine Referenz.



  • Das ist der Unterschied, ob man eine Referenz oder eine Kopie an die Funktion weitergibt.

    "passing by reference vs. passing by value"

    Mal angenommen, du hast irgendeine Klasse die im Konstruktor richtig viel Zeit verbringt (weil sie dort Sachen berechnen muss oä), dann ist das erstellen einer Kopie halt teuer (zeitlich gesehen). Wenn du nun ein Objekt dieser Klasse als "value" weitergibst (halt ohne das '&'), würde eine Kopie erzeugt werden.
    In so einem Fall benutzt man dann aber besser Referenzen, um solche Objekte weiterzugeben. Dann wird kein neues Objekt erzeugt sondern es wird innerhalb der Funktion auf dem übergebenen Objekt weiter gearbeitet. Um zu Kennzeichnen, dass man ein Objekt als Referenz an eine Funktion weitergeben will, nutzt man halt '&' hinter dem Datentypen des Parameters.

    Ein weiteres Thema mit dem du dich in diesem Zusammenhang beschäftigen solltest wäre "const-correctness".

    Ich hoffe mal das ist jetzt nicht zu falsch erklärt. Von einem Anfänger für einen C-Lerner.



  • Okay, dann hab ich das soweit erstmal verstanden.

    Vielen Dank


Anmelden zum Antworten