pointer in vectoren, wann sinnvoll?



  • Hallo,

    Ich bin gerade dabei, mir C++ anzueignen und bin dabei auf etwas gestoßen, dessen Sinn ich (noch) nicht ganz verstehe.
    Auch auf die Gefahr hin, dass ihr euch lustig macht, würde ich gerne wissen, wann es in euren Augen sinnvoll ist in einem stl vector oder sonstigen stl containern zeiger zu haben und wann nicht? Polymorphie leuchtet mir ein, aber gibt es sonst noch etwas? Ich habe Beispiele gesehen mit stl Container gesehen, die pointer beinhalten, ich aber nicht verstanden habe wozu? Außer, dass das Programm aufgrund der Speicherbereinigung an die derjenige denken musste unnötig kompliziert wurde.

    Vielleicht gibt es ja doch jemanden, der sich erbarmt 🙂

    Viele Grüße
    T1m


  • Mod

    So kann man zum Beispiel eine Liste haben, die gleichzeitig nach Kriterium A und gleichzeitig nach Kriterium B sortiert ist, um mal ein einfaches Beispiel zu nennen.



  • SeppJ schrieb:

    So kann man zum Beispiel eine Liste haben, die gleichzeitig nach Kriterium A und gleichzeitig nach Kriterium B sortiert ist, um mal ein einfaches Beispiel zu nennen.

    Verstehe ich nicht so ganz. Wie geht das?
    Und bei Polymorphie würde ich eher zu unique_ptr greifen..


  • Mod

    cooky451 schrieb:

    Verstehe ich nicht so ganz. Wie geht das?

    #include <vector>
    #include <iostream>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    struct Foo
    {
      int a,b;
      Foo(int a, int b): a(a), b(b) {}
      friend ostream& operator<<(ostream &out, const Foo& foo) 
       {return out << '(' << foo.a << ',' << foo.b << ')';}
    };
    
    bool asmaller(Foo lhs, Foo rhs) {return lhs.a < rhs.a;}
    bool bsmaller(Foo *lhs, Foo *rhs) {return lhs->b < rhs ->b;}
    
    int main()
    {
      vector<Foo> foos;
      vector<Foo*> foops;  
    
      for (int i = 0; i < 10; ++i)
        foos.push_back(Foo(rand(), rand()));
      for (int i = 0; i < 10; ++i)
        foops.push_back(&foos[i]);
    
      sort(foos.begin(), foos.end(), asmaller);
      sort(foops.begin(), foops.end(), bsmaller);
    
      cout << "Sortiert nach a:\n";
      for (int i = 0; i < 10; ++i)
        cout << foos[i] << '\n';
      cout << "Sortiert nach b:\n";
      for (int i = 0; i < 10; ++i)
        cout << *foops[i] << '\n'; 
    }
    

    Dieses Beispiel ist ein bisschen zu einfach, um sinnvoll zu erscheinen. Es geht allgemein da drum, dass man manchmal auf Daten auf unterschiedliche Weise zugreifen muss, so dass man unterschiedliche Containermodelle braucht, um das effizient zu machen. Oder man braucht für einen Algorithmus nur bestimmte Objekte aus einer größeren Datenmenge, die ansonsten untrennbar zusammen gehört.



  • mh aber gerade sowas sollte man doch eher mit einem shared_ptr machen, bearbeitet mand en einen vector (löschen z.b.) dann muss mand en anderen auch editieren. das kannd er nutzende programmierer aber doch auch gerne mal vergessen und schwups implodiert die division durch 0

    (es sei denn man kapselt das alles in eine klasse)


  • Mod

    Huh? Ich habe hier nicht einmal ein new, wo will ich da noch einen shared_ptr für haben?

    Beide Vectoren sind natürlich in einer Klasse gekapselt, die sich um die ganze Verwaltung kümmert, aber ich mag nicht > 10 Minuten an einem Beispiel schreiben.



  • vector<Foo*> foops;   
    Foo * f = new Foo(1,2);
    foops.push_back(f);
    sort(foops.begin(), foops.end(), bsmaller);
    

    Wenn der Copy-Ctor und operator= von Foo teuer sind, habe ich schon so etwas gesehen.
    In C++11-Zeiten ist das nicht mehr nötig, da Foo dann einen Move-Ctor und Move-Assignment-Operator haben sollte.


Anmelden zum Antworten