Einfacher Zeiger vs new-Ersteller Zeiger



  • Man kann keine Referenzen in Containern speichern, Referenzen sind keine Objekte.
    

    Meinst du damit jetzt "man kann wirklich nicht" oder "man sollte nicht"?
    Wenn man Pointer speichern kann, warum dann nicht auf Referenzen? Verstehe ich nicht.



  • Firefighter schrieb:

    Ich hab versucht ein std::vector<Account&> zu erstellen, aber das ging nich wirklich.
    Wollte halt keine unnötigen Kopien speichern. Wenn du mir sagst was bei meiner Deklaration des Vectors falsch ist, dann würde ich das sofort umbauen, wäre mir sowieso lieber.

    Referenzen können nicht in einen Container gepackt werden - und selbst wenn, benötigst du immer noch ein referenziertes Objekt, das lange genug überlebt, um es nutzen zu können. Besser ist es, die Werte direkt in einen std::vector<Account> zu packen. Und solange die verwendeten Objekte nicht extrem groß oder kompliziert aufgebaut sind, ist die Kopie auch nicht wirklich problematisch.
    (eventuell kann man sogar die move-Semantik in C++0x nutzen, um die Kopie zu umgehen)


  • Mod

    Ich meine: Warum kein std::vector<Account> ? Du magst semantische Gründe dafür haben, die ich nicht kenne, weil ich das Beispiel nicht komplett kenne. Aber soweit ich das Beispiel sehe, frage ich mich, wieso eine Bank nur Verweise auf ihre Konten haben sollte. Die Konten liegen schließlich bei der Bank.



  • CStoll schrieb:

    Firefighter schrieb:

    Ich hab versucht ein std::vector<Account&> zu erstellen, aber das ging nich wirklich.
    Wollte halt keine unnötigen Kopien speichern. Wenn du mir sagst was bei meiner Deklaration des Vectors falsch ist, dann würde ich das sofort umbauen, wäre mir sowieso lieber.

    Referenzen können nicht in einen Container gepackt werden - und selbst wenn, benötigst du immer noch ein referenziertes Objekt, das lange genug überlebt, um es nutzen zu können. Besser ist es, die Werte direkt in einen std::vector<Account> zu packen. Und solange die verwendeten Objekte nicht extrem groß oder kompliziert aufgebaut sind, ist die Kopie auch nicht wirklich problematisch.
    (eventuell kann man sogar die move-Semantik in C++0x nutzen, um die Kopie zu umgehen)

    Dank dir, dann werd ich es ohne Zeiger machen.

    Aber mal ne Allgemeine Frage, wann ist "kompliziert, kompliziert genug" um auf Zeiger zurückzugreifen. Wird ja sicherlich keine Goldene Regel dafür geben oder?
    Oder kann ich pauschal sagen: Ab 3,4,5... anderen benutzerdefinierten Objekten in der Klasse, sollte ich nen Zeiger nehmen wenn ich es in nem Container speicher oder in Funktionen umherreiche?



  • Firefighter schrieb:

    Ja ich hab ich doch. Die Deklaration des Containers sieht so aus:

    std::vector<Account*> accounts;
    SeppJ meinte aber eben, warum ich Zeiger speicher und nicht die Accounts selbst, ich dachte damit bezieht er sich auf Referenzen. Ich hab das anscheind falsch verstanden.

    Du kannst auch Folgendes machen:

    std::vector<Account> accounts;
    Account a(money,kredit);
    accounts.push_back(a);
    

    Dabei wird zwar nicht das eigentliche Objekt gespeichert, sondern eine Kopie davon im Vektor erzeugt...


  • Mod

    Firefighter schrieb:

    Aber mal ne Allgemeine Frage, wann ist "kompliziert, kompliziert genug" um auf Zeiger zurückzugreifen. Wird ja sicherlich keine Goldene Regel dafür geben oder?
    Oder kann ich pauschal sagen: Ab 3,4,5... anderen benutzerdefinierten Objekten in der Klasse, sollte ich nen Zeiger nehmen wenn ich es in nem Container speicher oder in Funktionen umherreiche?

    Das kommst drauf an, wie teuer eine Kopie ist und ob du überhaupt (außer ganz am Anfang) kopieren musst. Teuer wird eine Kopie bei abertausenden von Bytes pro Objekt. Aber man muss oft gar nicht Kopieren. Oftmals füllt man am Anfang des Programms seinen Container und reicht diesen immer per Referenz rum. Dann ist mehr oder weniger egal, was drin ist. Teuer wird die Sache erst, wenn etwas macht, was internes umherkopieren auslöst, z.B. ein Element aus der Mitte eines vectors löschen. Aber wenn man so etwas hat, dann war wohl vector an sich eine schlechte Wahl als Container. Auf jeden Fall hätte man dann nur die Wahl zwischen langsam und sehr langsam, daher hat man wohl schlechtes Design und sollte vielleicht eine list oder ein set nehmen.

    Also ja, die Frage ist schwer zu beantworten. Aber nimm nicht ohne Not aus technischen Gründen Pointer. Sieh erst einmal zu, dass die Semantik deines Programms stimmt, Geschwindigkeitsoptimierungen sind etwas für später, wenn es läuft.



  • SeppJ schrieb:

    Firefighter schrieb:

    Also ja, die Frage ist schwer zu beantworten. Aber nimm nicht ohne Not aus technischen Gründen Pointer. Sieh erst einmal zu, dass die Semantik deines Programms stimmt, Geschwindigkeitsoptimierungen sind etwas für später, wenn es läuft.

    Jo das ist klar. Ich hatte wohl zu viel Vor-Optimieren wollen und wir kennen ja alle Knuths Antwort auf dieses Problem.

    Danke für die Antworten 😉



  • Firefighter schrieb:

    Aber mal ne Allgemeine Frage, wann ist "kompliziert, kompliziert genug" um auf Zeiger zurückzugreifen. Wird ja sicherlich keine Goldene Regel dafür geben oder?
    Oder kann ich pauschal sagen: Ab 3,4,5... anderen benutzerdefinierten Objekten in der Klasse, sollte ich nen Zeiger nehmen wenn ich es in nem Container speicher oder in Funktionen umherreiche?

    Feste Grenzen gibt es da wohl nicht, eher eine Grauzone, wo es von der Anwendung abhängt, ob die Kopie vertretbar ist. Wenn du das Ganze in einer zeitkritischen Schleife ausführst, kann schon die Kopie eines vector<> oder std::string dich ausbremsen, an einer Stelle, die nur selten verwendet wird, kannst du auch große Objekte problemlos kopieren.
    Das einzige Hindernis wäre es höchstens, wenn du mit Objekten arbeitest, die nicht kopiert werden können (z.B. io-Streams).

    theliquidwave schrieb:

    Man kann keine Referenzen in Containern speichern, Referenzen sind keine Objekte.
    

    Meinst du damit jetzt "man kann wirklich nicht" oder "man sollte nicht"?
    Wenn man Pointer speichern kann, warum dann nicht auf Referenzen? Verstehe ich nicht.

    In dem Fall heißt das "man kann wirklich nicht" - Elemente für STL-Container müssen Kopier-Konstruktion und Zuweisung ermöglichen, und letzteres klappt mit Referenzen nicht.



  • Firefighter schrieb:

    Aber mal ne Allgemeine Frage, wann ist "kompliziert, kompliziert genug" um auf Zeiger zurückzugreifen. Wird ja sicherlich keine Goldene Regel dafür geben oder?

    Generelle Antwort: Wenn du einen Vorteil davon hast. Der Normalfall sind Objekte, für Zeiger solltest du einen speziellen Grund haben. Unabdingbar sind sie z.B. bei nichtkopierbaren oder polymorphen Objekten.

    Aber in diesen Fällen gibt es z.B. auch Boost.PointerContainer, welche exceptionsicher sind, automatisch aufräumen und direkt dereferenzieren.



  • XSpille schrieb:

    [
    Du kannst auch Folgendes machen:

    std::vector<Account> accounts;
    Account a(money,kredit);
    accounts.push_back(a);
    

    Warum dann nicht gleich so?

    std::vector<Account> accounts;
    accounts.push_back(Account(money,kredit));
    

Anmelden zum Antworten