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_ptrs, 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

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -