type erasure - dynamic_cast problem



  • Hi,
    ich habe höchstwahrscheinlich ein kleines Verständnis Problem bei dynamic_cast oder der Anwendung von type erasure.

    Ich habe eine Basisklasse:

    class json_basic{ json_basic(){} virtual json_basic(){}};
    
    template<typename T>
    class json_value : public json_basic
    {
    public: 
    json_value(T value) : value_(value) {}
    virtual ~json_value(){}
    T value_;
    };
    
    class JSON
    {
    JSON() {}
    ~JSON() {}
    
    unordered_map<string, json_basic> children;
    
    template<typename T>
    const T & get_cref()
    {
    json_value<T> * ptr;
    		auto it = children.find(search);
    
    		if (it != children.end())
    		{
    			ptr = dynamic_cast <json_value<T>*>(it->second.get());
    
    			return ptr->value_;
    		}
    }
    };
    

    Soweit so gut.
    Mein Problem ist jetzt, dass natürlich der unique_ptr für ein solches Datenmodell ungeeignet ist, weil ich nicht in der Lage bin meine Objekte zu kopieren.
    Ich könnte auch auf shared_ptr umsteigen und alles würde funktionieren allerdings hätte ich gerne ein richtiges copy.

    Ist es möglich dynamic cast auf normalen Objekten oder referencen zu casten?
    Ich habe das nämlich semantisch nicht hingekriegt.

    Beim Versuch einen richtigen Copy Construktor zu schreiben und den Value auf den der unique_ptr zeigt zu kopieren bin ich leider gescheitert, da meine json_values nicht wissen, was für ein Datentyp sie sind.

    Jemand eine Idee?

    Gruß



  • Du brauchst so etwas wie unique_ptr. Der Kopierkonstruktor ruft dann für jedes Element eine neue virtuelle Methode clone() auf, die einen unique_ptr<json_basic> als Kopie von sich zurückliefert.



  • Hi Nathan,
    entschuldige aber so ganz habe ich deine Antwort nicht verstanden.
    Ich habe es mal so gebaut, wie ich es verstanden habe, aber ich bekomme einen initializing error: cannot convert frm 'json_value<T>' to 'std::unique_ptr<json_basic, std::default_delete<_Ty>>, error.

    class json_basic
    { 
    json_basic(){} 
    virtual json_basic(){}};
    virtual unique_ptr<json_baisc> clone() {}
    
    template<typename T>
    class json_value : public json_basic
    {
    public: 
    json_value(T value) : value_(value) {}
    virtual ~json_value(){}
    T value_;
    
    virtual unique_ptr<JSON_basic> clone()
    {
       unique_ptr<JSON_basic>temp = this;
       return temp;
    }
    };
    
    class JSON
    {
    JSON() {}
    ~JSON() {}
    
    unordered_map<string, json_basic> children;
    
    template<typename T>
    const T & get_cref()
    {
    json_value<T> * ptr;
            auto it = children.find(search);
    
            if (it != children.end())
            {
                ptr = dynamic_cast <json_value<T>*>(it->second.get());
    
                return ptr->value_;
            }
    }
    };
    


  • virtual unique_ptr<json_baisc> clone() {}
    
    virtual unique_ptr<JSON_basic> clone()
    {
       unique_ptr<JSON_basic>temp = this;
       return temp;
    }
    

    Könntest du uns bitte den richtigen Code zeigen? Hier weiss man gar nicht, was falsch ist und was nur falsch kopiert wurde.

    Die Implementierung muss natürlich so aussehen:

    virtual unique_ptr<JSON_basic> clone()
    {
       return unique_ptr<JSON_basic>(new json_value(*this));
       // oder besser seit C++14
       return make_unique<json_value>(*this);
    }
    


  • klaun schrieb:

    virtual unique_ptr<json_baisc> clone() {}
    
    virtual unique_ptr<JSON_basic> clone()
    {
       unique_ptr<JSON_basic>temp = this;
       return temp;
    }
    

    Könntest du uns bitte den richtigen Code zeigen? Hier weiss man gar nicht, was falsch ist und was nur falsch kopiert wurde.

    Die Implementierung muss natürlich so aussehen:

    virtual unique_ptr<JSON_basic> clone()
    {
       return unique_ptr<JSON_basic>(new json_value(*this));
       // oder besser seit C++14
       return make_unique<json_value>(*this);
    }
    

    Entschuldigung, ich hätte nochmal genauer kontrollieren sollen.
    Ich wollte euch auch nicht mit zuviel Code belästigen.

    Zu deinem Code:
    Danke!!!
    Hat mein Problem vollkommen gelöst und funktioniert einwandfrei, nachdem ich clone() in CTOR und Copy-Operator eingebaut hatte.


Log in to reply