c++ - Indicating (non) transfer of ownership with unique_ptr -
suppose have class this:
class node { public: node(node* parent = 0) : mparent(parent) {} virtual ~node() { for(auto p : mchildren) delete p; } // takes ownership void addchild(node* n); // returns object ownership node* firstchild() const; // not take ownership void setparent(node* n) { mparent = n; } // returns parent, not transfer ownership node* parent() const { return mparent; } private: list<node*> mchildren; node* mparent; };
i'd use smart pointers and/or rvalue references indicate ownership , isn't transferred.
my first guess change mchildren
contain unique_ptr
s, adapting function signatures follows.
// takes ownership void addchild(unique_ptr<node> n); // returns object ownership unique_ptr<node>& firstchild() const; // not take ownership void setparent(node* n) { mparent = n; } // returns parent, not transfer ownership node* parent() const { return mparent; }
now, kind of problematic when need pass result of node::firstchild()
function observes it, not take ownership, i'd need explicitly call .get()
on unique_ptr
, understand it, not recommended.
what correct , recommended way indicate ownership using unique_ptr
without having resort using .get()
, passing around bare pointers?
at first, use std::vector
rather std::list
contain children. unless have strong motivation not using it, std::vector
should default container. if worried performance, don't be, because contiguous allocation done std::vector
cause higher cache hit rate, speeding access enormously respect std::list
, implies scattered allocation/access pattern.
secondly, correct in having std::vector<std::unique_ptr<node>>
holding children, since reasonable assume node hold ownership of child nodes. other pointers except 1 accepted addchild()
, on other hand, should non-owning raw pointers.
this applies mparent
pointer , pointers returned node
's member functions. in fact the, firstchild()
member function return reference, throwing exception if node has no children. way create no confusion whatsoever owning returned object.
returning unique_ptr
, or reference unique_ptr
, not correct idiom: unique pointers represent ownership, , not want give ownership clients of node
.
this how class like:
#include <vector> #include <memory> #include <stdexcept> class node { public: node() : mparent(nullptr) { } void addchild(std::unique_ptr<node>&& ptr) { mchildren.push_back(std::move(ptr)); ptr->setparent(this); } node& firstchild() const { if (mchildren.size() == 0) { throw std::logic_error("no children"); } else return *(mchildren[0].get()); } node& parent() const { if (mparent == nullptr) { throw std::logic_error("no parent"); } else return *mparent; } private: void setparent(node* n) { mparent = n; } std::vector<std::unique_ptr<node>> mchildren; node* mparent; };
you of course decide return non-owning, potentially null raw pointers instead of references if want avoid throwing exceptions. or add pair of hasparent()
, getnumofchildren()
methods retrieve information node
's state. allow clients perform check if not want handle exceptions.
Comments
Post a Comment