Smartpointer-Hype vs. Over-Dev
-
Ich finde Klassen werden aktuell echt gehypet. Die werden irgendwie überall zu viel benutzt. Ich habe mir da deshalb meine eigene.............
-
chp++ schrieb:
oder an der Stelle an der entschieden wird ,dass das Objekt zerstört werden muss.
Ich habe es jetzt an genau dieser Stelle eingebaut. Die Dungeons kennen die alle Kameras - im Moment habe ich im Splitscreen bis zu 4 Kameras, d.h. der Aufwand hält sich in Grenzen. Und die Kameras werden über das Verschwinden der Objekte informiert:
void Camera::notify(DungeonEvent const & event) { if (event.type == DungeonEvent::Type::ObjectVanished) { if (focus == event.object) { focus = nullptr; } } }chp++ schrieb:
Du solltest dort nach meiner Meinung auch nix auf nullptr setzen, sondern das Element komplett rauslöschen.
Die Camera-Instanz besitzt ein Attribut
GameObject* focus- das setze ich halt um wenn die Kamera einem anderen Objekt folgtchp++ schrieb:
Wenn ich so länger darüber nachdenke, solltest du auf jedenfall messen, was schneller ist. Ein vector mit bruteforce search, wäre im Hinblick auf Performance mit wenigen Elementen wahrscheinlich um ein vielfaches schneller.
Auch wenn du in der Mitte löschen musst.
Wenn du in deiner Kamera keine "Z-Order" brauchst (Reihenfolge) kannst du auch mit dem letzten Element swappen und dann poppen.Den Ansatz der linearen Suche auf einem Vector werde ich mir für geeignete Stelle merken, Danke
!!@Archti:

-
Marthog schrieb:
smart pointer verhindern, dass speicher leaked und das auch bei exceptions.
bei mir leakt bei exceptions nichts, und ich muß momentan projektbedingt in "klassischem" C++ ohne smart pointers programmieren.
Kennst Du eine Situation, in der memory leaks bei exceptions unabwendbar sind?
-
großbuchstaben schrieb:
bei mir leakt bei exceptions nichts, und ich muß momentan projektbedingt in "klassischem" C++ ohne smart pointers programmieren.
Gewagte Aussage. Die meisten die das behauptet haben haben immer noch doof geguckt.
Klar, ein Programm dass im Standardfall nicht leakt ist auch ohne RAII keine Kunst. Ein Programm das in keinem denkbaren Sonderfall leakt ... ohne RAII, aber mit Exceptions ... ist schon ne Herausforderung.großbuchstaben schrieb:
Kennst Du eine Situation, in der memory leaks bei exceptions unabwendbar sind?
Unabwendbar sind sie nie.
Bloss muss man verflixt aufpassen. ODER, was die schlauere Variante ist, sich seine eigenen RAII Hilfsklassen schreiben.Oft sieht man z.B. so Sachen wie
Thing t = AllocateThing(); DoStuffThatCannotThrow(t, somePath + "\\file.ext"); // operator +(std::string const&, char const*) => std::bad_alloc => Leak ReleaseThing(t);
-
großbuchstaben schrieb:
Marthog schrieb:
smart pointer verhindern, dass speicher leaked und das auch bei exceptions.
bei mir leakt bei exceptions nichts, und ich muß momentan projektbedingt in "klassischem" C++ ohne smart pointers programmieren.
Kennst Du eine Situation, in der memory leaks bei exceptions unabwendbar sind?
Zeig mal, wie du ein Array von Strings via new allozierst. Exceptionsafe. Ohne Leak.
-
@Nathan
Ich verstehe grad das Problem nicht.
Also wo da eine Exception fliegen soll, und wo dann was leaken soll. Und was genau du mit "Array von Strings" meinst.Alles was mir an Möglichkeiten einfällt kann man, wenn man dran denkt, mit
catch (...) { do_the_cleanup(); throw; }abdecken.
Ist bäh, aber funktioniert.Oder steh' ich grad auf der Leitung?
-
Nathan schrieb:
großbuchstaben schrieb:
Marthog schrieb:
smart pointer verhindern, dass speicher leaked und das auch bei exceptions.
bei mir leakt bei exceptions nichts, und ich muß momentan projektbedingt in "klassischem" C++ ohne smart pointers programmieren.
Kennst Du eine Situation, in der memory leaks bei exceptions unabwendbar sind?
Zeig mal, wie du ein Array von Strings via new allozierst. Exceptionsafe. Ohne Leak.
ich würde std::vectorstd::string nehmen, und new vermeiden, stattdessen automatischen Destruktor-Aufruf beim Verlassen des scopes ausnutzen. Wieso sollte bei new/delete mit exceptions zwangsläufig ein leak entstehen?
-
Hi, inzwischen habe ich eine eigene Implementierung auf Basis von
std::unique_ptrgebaut:sole_ptr(owning) und sein "observing" Gegenstückdynamic_ptr(non-owning). Hier die grobe Idee:dynamic_ptrbesitzen einen (nativen) Zeiger (nennen wir ihnparent) auf einensole_ptr- sie "melden" sich bei diesem "an", d.h. ein
sole_ptrkennt alledynamic_ptrdie sich angemeldet haben - Gibt der
sole_ptrsein gehaltenes Objekt frei, werden alledynamic_ptrinformiert und ihreparentZeiger aufnullptrgesetzt. Ok, das ginge auch mit einem Customized Deleter ^^ - Wird ein
sole_ptrverschoben (hier wird es interessant), informiert er auch alledynamic_ptrdarüber und sagt ihnen, welchersole_ptrnun die bisherige Ressource verwaltet. Dadurch werdendynamic_ptrnach einemstd::moveauf einemscope_ptrnicht ungültig (oder zeigen auf einen leeren smartpointer). - Ob ein
dynamic_ptrungültig ist kann mitbool expired() const;abgefragt werden
Haters gonna hate. Alle anderen finden den Code auf GitHub:
- Implementierung (header-only da template-only): https://github.com/cgloeckner/std_ext/blob/master/include/sole_ptr.hpp
- Testcases und Beispielcode: https://github.com/cgloeckner/std_ext/blob/master/test/sole_ptr_test.cpp
konstruktives Feedback erwünscht

Testcode in a nutshell:
// [...] Rest siehe Testcase-Code struct Foo { int id; std::string name; Foo(int id, std::string const & name) : id{id} , name{name} { std::cout << "+" << this << "\n"; } virtual ~Foo() { std::cout << "-" << this << "\n"; } }; int main() { // create sole ownership auto owner = make_sole<Foo>(42, "Anonymous"); // create non-owning pointer dynamic_ptr<Foo> user{owner}; // operate on `user` user->id++; user->name += std::to_string(user->id); if (!user.expired()) { std::cout << "Foo[" << user->id << "," << user->name << "]\n"; } else { // this cannot happen in this case, because user didn't expire, yet std::cout << "Foo expired (unexpected!!)\n"; return 1; } // move ownership auto other = std::move(owner); std::cout << "After moving ownership, non-owning expired() is " << user.expired() << "\n"; // end ownership other = nullptr; std::cout << "After ownership ended, non-owning expired() is " << user.expired() << "\n"; }LG Glocke
-
Glocke schrieb:
Haters gonna hate.
Also den Spruch, und die dem Spruch zu Grund liegende Einstellung, finde ich reichlich doof.
Davon abgesehen... was du da zusammengebastelt hast macht mMn. schon Sinn.
Threadsafe ist es halt nicht, bzw. es ist nicht ohne signifikanten Aufwand threadsafe zu bekommen. Was aber für viele Anwendungen egal ist.
-
hustbaer schrieb:
Also den Spruch, und die dem Spruch zu Grund liegende Einstellung, finde ich reichlich doof.
Wer an dieser Stelle lieber shared_ptr nimmt, kann das machen und meine Lösung als Unfug abtun .. alle anderen dürfen über den Spruch schmunzeln und müssen keine tiefere Bedeutung hineininterpretiere 
hustbaer schrieb:
Davon abgesehen... was du da zusammengebastelt hast macht mMn. schon Sinn.
Threadsafe ist es halt nicht, bzw. es ist nicht ohne signifikanten Aufwand threadsafe zu bekommen. Was aber für viele Anwendungen egal ist.Thread- und Exception-safety stehen schon auf der Todo-Liste

-
Ähm.
Wenn du es threadsafe machen willst, dann kannst du gleich genau so gut internshared_ptrundweak_ptrverwenden. Und dir damit nen Haufen Arbeit sparen.
Weil es dann genau so langsam wird.Bzw. ... genaugenommen kannst du es gar nicht threadsafe machen ohne weitere Umbauten.
Weil du, wenn es threadsafe sein soll, dieweak_ptr::lockSemantik brauchst.
Sonst könnte dir ja ein anderer Thread den "sole_ptr" resetten während dein Thread gerade auf das Objekt zugreift.Also... wenn du eine Lösung anzielst die threadsafe ist... dann würde ich wirklich sagen: das ist Unsinn.
-
Und wieso virtuelle Destruktoren?
-
Nathan schrieb:
Und wieso virtuelle Destruktoren?
Gewohnheit :S
@hustbaer: schau ich mir mal genauer an