SharedPtr<Base> mit "Derived" class



  • Enumerator schrieb:

    @KasF
    Hi danke für deinen Tipp, funktioniert aber leider auch nicht:

    template <class U>
    	SharedPtr::SharedPtr(const SharedPtr<U>& value) :
    		_value(value._value)
    	{
    	}
    

    Das SharedPtr:: muss weg. Du schreibst bei den anderen Methoden und Konstruktoren in der Klassen ja auch kein SharedPtr davor.

    http://ideone.com/2ZKLQz



  • daddy_felix schrieb:

    solange du dich im selben Thread befindest, absolut unproblematisch.

    Das ist absolut unproblematisch. Deine beschriebenen Fälle sind nur mit Fehlanwendungen von Threading möglich, da liegt der Fehler aber nicht bei der Funktion.

    Enumerator schrieb:

    Und einen SharedPtr als rohen Pointer zu übergeben ist ja wohl total bescheuert. Denn dann hat der SharedPtr womöglich das Objekt gelöscht und man übergibt einen dangling Pointer. Super.
    Evtl. könnte man den SharedPtr als const Ref übergeben, aber bin mir nicht sicher ob das nicht auch wieder problematisch ist.

    Wie ich Leute hasse, die C++ nicht verstehen und überall Fehlerquellen sehen, gegen die sie sich mehrfach absichern müssen. Hat sogar einen Namen: Cargo cult programming.

    Ich verstehe zwar nicht, wozu man erlauben möchte, dass das Argument ein nullptr ist, aber

    void Test1(Base const& test);
    void Test2(Base const* test);
    
    shared_ptr<Base> b = ...
    Test1(*b);      // 100% sicher, kein Fehler denkbar
    Test2(b.get()); // 100% sicher, kein Fehler denkbar
    

    ist immer korrekt.



  • Enumerator schrieb:

    Ah, stand auf dem Schlauch. So gehts:

    template <class U>
    	SharedPtr(const SharedPtr<U>& value) :
    		value(value)
    	{
    	}
    

    Und wie schreibe ich das ganze nun außerhalb der SharedPtr-Klasse?
    So gehts nicht:

    template <class T>
        template <class U>
    	SharedPtr<T>::SharedPtr(const SharedPtr<U>& value) :
    		value(value)
    	{
    	}
    
    // Deklaration in Klasse
    template <class U> 
    SharedPtr(const SharedPtr<U>& value);
    
    // Definition außerhalb
    template<typename T>
    template<typename U>
    SharedPtr<T>::SharedPtr(const SharedPtr<U> &value)
     : _value(value._value)
    { }
    


  • @Sherry
    Die tatsächliche Funktion heißt aber nicht Test sondern Add und fügt den SharedPtr einer Liste hinzu. Würde ich nur den rohen Zeiger nehmen. Wäre es also 100%tig falsch.



  • sharry schrieb:

    void Test1(Base const& test);
    void Test2(Base const* test);
    
    shared_ptr<Base> b = ...
    Test1(*b);      // 100% sicher, kein Fehler denkbar
    Test2(b.get()); // 100% sicher, kein Fehler denkbar
    

    ist immer korrekt.

    void Test2(Base const* test)
    {
        delete test;
    }
    


  • @KasF
    Jetzt hatte ich vor lauter Hektik die Deklaration in der Klasse noch ausgeklammert gehabt. Super, funktioniert nun. Danke euch für die Hilfe.



  • Enumerator schrieb:

    @ptr^^
    Ich schreibe keinen SharedPtr, das ist nur ein Beispiel. Ich schreibe einen "CustomPtr" da es für mein Problem keinen geeigneten SmartPtr gibt und das Konzept der SmartPointer von std und boost einfach Schrott ist.

    Genauso klingt ein Kollege von mir. Und weisst du was? Oberflächlich denkt man, dass er weiss wovon er spricht. Aber er hat letztlich keine Ahnung. Und genau den Eindruck machst du auch, gerade durch solche schwachsinnigen Aussagen.

    Ich denke du bist immer noch dran deine komische Baumstruktur mit Controls und was weiss ich darzustellen, richtig?

    Dann erklär mal lieber, was du mit deinem "CustomPtr" vorhast, wie er funktionieren soll und wo er besser oder schlechter ist als shared_- oder unique_ptr.



  • Dafür liebe ich euch ;). Kaum geht man mal einen anderen Weg ist man der Böse. Ich habe ja wie du weißt ein wenig mit den Smartpointern rumexperimentiert und halt festgestellt, dass es für mein Problem keinen passenden gibt. Z.B. hätte ich das Problem von "Smart-Pointer-Kollisionen". Was machst du wenn du eine Liste von shared_ptrn hast aber nun auch einen Unique-Pointer oder Weak-Pointer ebenfalls darin speichern möchtest?
    Die Lösung ist ganz einfach. Anstatt mehrerer SmartPointer-Typen gibt es bei mir nur einen. Diese können bei Bedarf mit einem Flag versehen werden, das angibt ob er Strong, Weak oder Unique ist. Da alle std Smart-Pointer sowieso mehr oder weniger nur eine Untermenge des shared_ptrs sind macht eine Trennung meiner Meinung nach eh keinen Sinn. Den Overhead durch den unnützen RefCounter-Pointer für z.B. einen WeakPointer nehme ich in kauf und denke es ist vertretbar.
    Und das beste. Bislang integriert sich dieser Pointer wunderbar in mein Framework. Die std Smart-Pointer dagegen nicht. Wenn ihr mit diesen klar kommt bitte, aber ich habe für mich festgestellt, dass die std-Library für Standard-Sachen nett ist. Für spezielle Dinge aber eben nicht.
    Und sei doch mal ehrlich. Diese Smart-Pointer-Geschichte ist doch eine einzige Krücke. Leider ist Kritik an der Std-Library scheinbar nicht erlaubt.
    Schade, denn sonst würden im Jahr 2013 vielleicht auch schon so "extravagante" Dinge wie namespaces usw. Verwendung finden .



  • Kaum geht man mal einen anderen Weg ist man der Böse.

    Wenn der "andere" Weg Blödsinn ist, dann schon, ja.

    Was machst du wenn du eine Liste von shared_ptrn hast aber nun auch einen Unique-Pointer oder Weak-Pointer ebenfalls darin speichern möchtest?

    Dann ist dein Design falsch, punkt. Entweder du brauchst eine Liste von shared_ptr oder nicht - wieso zum Teufel brauchst du Listen von verschiedenen Smart-Pointer-Typen?
    Das ist als würde man sagen, man hat eine Liste von vector s, und möchte jetzt eine list einfügen. Das sind zwei verschiedene Dinge, auch wenn sie vielleicht ähnlich erscheinen.

    Die Lösung ist ganz einfach. Anstatt mehrerer SmartPointer-Typen gibt es bei mir nur einen. Diese können bei Bedarf mit einem Flag versehen werden, das angibt ob er Strong, Weak oder Unique ist.

    Das ist ... so ein Blödsinn. Ich finde das lächerlich.

    Da alle std Smart-Pointer sowieso mehr oder weniger nur eine Untermenge des shared_ptrs sind

    Sind sie nicht! Wieso sollten sie das sein?

    Den Overhead durch den unnützen RefCounter-Pointer für z.B. einen WeakPointer nehme ich in kauf und denke es ist vertretbar.

    Nein, das ist er nicht.

    Und sei doch mal ehrlich. Diese Smart-Pointer-Geschichte ist doch eine einzige Krücke.

    Sei doch mal ehrlich, du hast keine verdammte Ahnung wovon du sprichst.

    Und genau den Eindruck machst du auch, gerade durch solche schwachsinnigen Aussagen.

    👍



  • Die Std-Library ist orthogonal ausgelegt. Es gibt keine zwei Funktionen oder Klassen die das gleiche machen. Deshalb das Konzept der Container mit den Iteratoren und den Algorithmen.

    Eine Ausnahme bildet da std::string, das ist eine hochgradig monolithische Klasse, deren Methoden alle durch Iteratoren und einem Algorithmus aus algorithm implementierbar sind.
    Ein weiterer Schwachpunkt war std::auto_ptr, der mittlerweile ja auch deprecated ist.

    Aber das schönste an der STL ist,d ass sie getestet ist und quasi keine Fehler innehat. Klar spacken gewisse Compiler (*hust hust* Sone komm her *hust hust*) manchmal rum und haben Bugs (gerade wenn es um Template Magie geht), aber insgesamt sind die großen Compiler in dem Bereich nahezu fehlerfrei, würde ich mal behaupten.

    Dass dein CustomPtr die Funktionalität der "offiziellen" Smart Pointer hier einkapselt und durch Flags steuerbar macht finde ich ja gar nichtmal schlecht. Aber ich würde (und empfehle es dir hiermit) intern trotzdem die std::***_ptr nutzen. Und mit Type-Erasure lässt sich da sicherlich was echt gutes draus basteln, so dass du eine (abstrakte) Oberklasse hast, die du an jeder Stelle verwenden kannst, Typinformationen aber trotzdem nicht verlierst und sie durch Flags steuern kannst.


Anmelden zum Antworten