wie die unique_ptr einsetzen?



  • hi

    ich versuche einen graph mit unique_ptr zu bauen, und habe bis jetzt diesen anfang:

    #include <iostream>
    #include <string>
    #include <memory>
    
    using namespace std;
    
    template<typename T>
    class TreeNode {
    public:
       TreeNode(const T& val) : val_(val) {}
      ~TreeNode() {}
    
       const T& getVal() const {return(val_);}
       void setVal(const T& val) {val_ = val;}
       void addChild(unique_ptr<TreeNode<T>> & p) {
          const T& other = p->getVal();
          if (other > val_)
             if (right_)
                right_->addChild(p);
             else
                right_ = p;
          else
             if (left_)
                left_->addChild(p);
             else
                left_ = p;
       }
       const unique_ptr<TreeNode<T>> getLeft() {return(left_);}
       const unique_ptr<TreeNode<T>> getRight() {return(right_);}
    
    private:
       T val_;
       unique_ptr<TreeNode<T>> left_;
       unique_ptr<TreeNode<T>> right_;
    };
    // typedef TreeNode<T> TreeNodeT ;
    
    using TreeStringNode = TreeNode<string>;
    
    
    int main() {
       auto node1 = make_unique<TreeStringNode>("abc");
       auto node2 = make_unique<TreeStringNode>("def");
       auto node3 = make_unique<TreeStringNode>("hij");
    
    
       node1->addChild(node2);
       // node1->addChild(node3);
       
    }
    

    Der Compiler sagt das es nicht geht die pointer an einander zu hängen:

    unique_ptr2.cc:50:25:   required from here
    unique_ptr2.cc:21:20: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = TreeNode<std::__cxx11::basic_string<char> >; _Dp = std::default_delete<TreeNode<std::__cxx11::basic_string<char> > >]'
                 right_ = p;
                 ~~~~~~~^~~
    


  • Ein unique_ptr besitzt das Objekt. Das scheint dir nicht wirklich klar zu sein.

    Ein unique_ptr& als Parameter ist fragwürdig. Dein konkretes Problem kannst du mit right_ = std::move(p); lösen.



  • Was als allererstes auffällt ist, daß ein TreeNode kein Tree ist und ein Tree kein TreeNode.



  • danke - das ist wohl eines der themen wo es noch ein bisschen was zu lesen gibt, z.b.

    https://thispointer.com/shared_ptr-binary-trees-and-the-problem-of-cyclic-references/

    oder

    https://codereview.stackexchange.com/questions/214850/implementing-a-binary-tree-in-c-using-stdunique-ptr

    interessant auch das kleine programm bzgl sizeof unique_ptr

    #include <iostream>
    #include <typeinfo>
    #include <memory>
    
    
    using namespace std;
    
    int main() {
    
    	typedef unique_ptr<int> unique_int_ptr;
    	int * raw_int_ptr;
    
    	cout << typeid(unique_int_ptr).name() << ": ";
    	cout << sizeof(unique_int_ptr) << endl;
    
    	cout << typeid(raw_int_ptr).name() << ": ";
    	cout << sizeof(raw_int_ptr) << endl;
    
    
    	return 0;
    
    }
    
    

    gibt:

    class std::unique_ptr<int,struct std::default_delete<int> >: 4
    int *: 4
    


  • @patrickm123 sagte in wie die unique_ptr einsetzen?:

    class std::unique_ptr<int,struct std::default_delete<int> >: 4
    int *: 4
    

    Eine der wohl herausragendsten Stärken von C++ ist, dass sich damit sehr hochlevelige Abstraktionen bauen lassen, die dennoch extrem leichtgewichtig sind. Dieser Größenvergleich gibt einem schon eine Idee, was das letzendlich bedeutet. Auch der erzeugte Code wird nahezu exakt derselbe sein, wie bei manuellem new/delete.



  • Also was ich mich noch irgendwie verwirrt ist der umgang mit unique_ptr und funktionen, z.b

    #include <iostream>
    #include <memory>
    
    using namespace std;
    
    auto unique_int_1() {
    	auto p = unique_ptr<int>(new int(123));
    	
    	return p;
    }
    
    void modify_p(unique_ptr<int> p) {
    	// *p = 234;
    }
    
    int main() {	
    	auto p = unique_int_1();
    	modify_p(p);	
    	cout << *p << endl;	
    	return 0;
    }
    
    

    der compiler will im main p nicht mehr in modify_p annehmen... p ist ja eine adresse, oder wie soll ich den fehler verstehen?

    ptrs_2.cc:24:12: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]'
    


  • ok, das hier tut was:

    #include <iostream>
    #include <memory>
    
    using namespace std;
    
    auto unique_int_1() {
    	auto p = unique_ptr<int>(new int(123));
    	
    	return p;
    }
    
    auto modify_p(unique_ptr<int> p) {
    	*p = 234;
    	return p;
    }
    
    int main() {
    	
    	auto p = unique_int_1();
    
    	p = modify_p(std::move(p));
    	
    	cout << *p << endl;
    	
    	return 0;
    }
    
    


  • @patrickm123

    @manni66 sagte in wie die unique_ptr einsetzen?:

    Ein unique_ptr besitzt das Objekt. Das scheint dir nicht wirklich klar zu sein.

    Wenn die Funktion einen unique_ptr als Parameter hat, übernimmt sie den Besitz!

    void modify_p(int& p) {
    	p = 234;
    }
    
    int main() {	
    	auto p = unique_int_1();
    	modify_p(*p);	
    


  • @patrickm123

    p = modify_p(std::move(p));
    	
    	cout << *p << endl;
    

    Nein! Den Pointer darfst du nach dem move nicht mehr dereferenzieren!

    Edit: ok, jetzt wird er zurück gegeben, dann ist das technisch Ok, aber nicht sinnvoll.



  • @manni66 wenn ich in einer funktion den inhalt des unique_ptr verändern will, move ich den pointer dann in den scope der funktion - oder kann ich eine Referenz auf den Inhalt übergeben? Mir ist die Umwandlung des unique_ptr zur Referenz aber nicht ganz klar.... dass die pointer ownership gemoved werden kann verstehe ich langsam.



  • @patrickm123 sagte in wie die unique_ptr einsetzen?:

    oder kann ich eine Referenz auf den Inhalt übergeben? Mir ist die Umwandlung des unique_ptr zur Referenz aber nicht ganz klar....

    Ja, das habe ich doch schon gezeigt:

    @manni66 sagte in wie die unique_ptr einsetzen?:

    void modify_p(int& p) {
    	p = 234;
    }
    
    int main() {	
    	auto p = unique_int_1();
    	modify_p(*p);	
    


  • Dieser Beitrag wurde gelöscht!


  • Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten