c++ - How does c++11 implements "... = default;" for the rule of three methods -
when learned c++ people told me always implement @ least rule of 3 methods.
now i'm seeing new "... = default;" c++0x on stack overflow, , question is:
is there c++11 standard implementation defined methods or compiler specific?
plus have precisions:
- what implementation looks in term of code? (if it's generic)
- does have advantage compared example implementation below?
- if don't use assignment/copy constructor,
*... = delete*
precisly, what's difference declaring them private? answer (from @40two)- is new default= different old default implementation?
disclaimer: when i'll need more advanced features in methods, sure i'll implements them myself. used implement assignment operator , copy constructor when never used them, in order compiler don't.
what used do: (edited, @ddrmmr swap/move)
//file t.h class t { public: t(void); t(const t &other); t(const t &&other); t &operator=(t other); friend void swap(t &first, t &second); ~t(void); protected: int *_param; }; //file t.cpp t::t(void) : _param(std::null) {} t::t(t &other) : _param(other._param) {} t::t(t &&other) : t() { swap(*this, other); } t &t::operator=(t other) { swap(*this, other); return (*this); } friend void swap(t &first, t &second) { using std::swap; swap(first._param, second._param); } t::~t(void) {}
the default behavior is:
- default ctor (
t()
): calls bases def. ctors , members default ctors. - copy ctor (
t(const t&)
): calls bases copy. ctors , members copy ctors. - move ctor (
t(t&&)
): calls bases move. ctors , members move ctors. - assign (
t& operator=(const t&)
): calls bases assign. , members assign. - transfer (
t& operator=(t&&)
): calls bases transfer, , members transfer. - destructor (
~t()
): calls member destructor, , bases destructor (reverse order).
for built-in types (int etc.)
- default ctor: set 0 if explicitly called
- copy ctor: bitwise copy
- move ctor: bitwise copy (no change on source)
- assign: bitwise copy
- transfer: bitwise copy
- destructor: nothing.
since pointers builtin types well, apply int*
( not points to).
now, if don't declare anything, t
class hold int* not own pointed int, copy of t hold pointer same int. same resulting behavior c++03. default implemented move built-in types copy. classes memberwise move (and depends on members are: copies built-ins)
if have change behavior, have coherently: example, if want "own" point to, need
- a default ctor initializing
nullptr
: defines "empty state" can refer later - a creator ctor initializing given pointer
- a copy ctor initializing copy of pointed (this real change)
- a dtor deletes pointed
- an assign deletes pointed , receive new copy of pointed
.
t::t() :_param() {} t::t(int* s) :_param(s) {} t(const t& s) :_param(s._param? new int(*s._param): nullptr) {} ~t() { delete _param; } // nothing if _param nullptr
let's not define assign, now, concentrate on move: if don't declare it, since declared copy, deleted: makes t object being copied if temporary (same behavior c++03)
but if source object temporary, can create empty destination , swap them:
t::t(t&& s) :t() { std::swap(_param, s._param); }
this called move.
now assignment: before c++11 t& operator=(const t& s)
should check against self assignment, make destination empty , receive copy of pointed:
t& operator=(const t& s) { if(this == &s) return *this; // can shortcut int* p = new int(s._param); //get copy ... delete _param; //.. , if succeeded (no exception while copying) ... _param = p; // ... delete old , keep copy return *this; }
with c++11 can use parameter passing generate copy, giving
t& operator=(t s) //note signature { std::swap(_param, s._param); return *this; }
note works in c++98, pass-by copy not optimized in pass-by move if s
temporary. makes such implementation not profitable in c++98 , c++03 convenient in c++11.
note there no need specialize std::swap
t: std::swap(a,b);
work, being implemented 3 moves (not copy)
the practice implement swap function derives case t has many members, being swap required in both move , assign. can regular private member function.
Comments
Post a Comment