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
keinTree
ist und einTree
keinTreeNode
.
-
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
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; }
-
@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);
-
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!