Special Member Functions CS 247: Software Engineering Principles Special Member Functions Readings: Eckel, Vol. 1 Ch. 11 References and the Copy Constructor Ch. 12 Operator Overloading ( operator= ) C++ member functions that are so important that the compiler will provide versions if we don't provide them: (0 parameters; generated iff we define no ) ( operator= ) U Waterloo CS247 (Spring 2017) p.1/20 U Waterloo CS247 (Spring 2017) p.2/20 Compiler-Generated Default Constructor If we do declare any for our class, the compiler will generate a for us: based on memberwise initialization. simple data members (built-in types): uninitialized pointer members: uninitialized member objects: initialized using members' s inherited members: initialized using base class Compiler-Generated Destructor If we do declare a for our class, the compiler will generate a for us: based on memberwise destruction simple data members: deallocated pointer members: pointer deallocated ( deleted) member objects: cleaned up using members' s inherited members: cleaned up using base class's U Waterloo CS247 (Spring 2017) p.3/20 U Waterloo CS247 (Spring 2017) p.4/20
Copy Constructor A constructs a new object whose value is equal to an existing object. - Used by the compiler to objects of the ADT. class Money; Money operator+ (Money m, Money n); int main() { Money m; Money n{m; Money p = m; p = p + n; U Waterloo CS247 (Spring 2017) p.5/20 Shallow copies the object and its pointers' addresses, so that the original and copied pointers refer to the same object. Deep copies the object and what its pointers point to, so that the pointer data members refer to distinct objects. Copying Objects with Pointers U Waterloo CS247 (Spring 2017) p.6/20 Compiler-Generated Copy Constructor If we do provide a or / or /, the compiler will generate a for us: based on memberwise simple data members: bitwise pointer members: bitwise member objects: copied using members' s inherited members: copied using base class's Copy is similar to the, except that the destination of the already exists. = ; // deep Copy Assignment Operator U Waterloo CS247 (Spring 2017) p.7/20 U Waterloo CS247 (Spring 2017) p.8/20
Compiler-Generated Assignment Operator If we do provide a / or /, the compiler will create a operator= member function for us: based on memberwise : simple data members: bitwise pointer members: bitwise member objects: uses members' operators inherited members: uses base class's operator = ; // shallow U Waterloo CS247 (Spring 2017) p.9/20 Copy-Swap Idiom Assignment operators may deal with pointer members by: creating a new object of the same type with the swapping the old values of the pointer members with the values in the newly created object letting the take care of deleting the old members but at the cost of efficiency!! // friend that swaps contents of m1 and m2 // using std::swap from <algorithm> void swap( MyClass & m1, MyClass &m2 ) { Base &b_m1 = static_cast<base&>(m1); Base &b_m2 = static_cast<base&>(m2); swap( b_m1, b_m2 ); std::swap( m1., m2. ); std::swap( m1., m2. ); std::swap( m1., m2. ); MyClass& MyClass::operator= (const MyClass& m) { MyClass temp{m; swap( *this, temp ); U Waterloo CS247 (Spring 2017) p.10/20 A constructs a new object whose value is equal to an existing object, but does preserve the value of the existing object. MyClass::MyClass (MyClass&& m) : Base{ std::(m), { std::(m.), { m.simple, { m. { m. = nullptr; Move Constructor To invoke members, need to pass an rvalue reference created by std::() Only requirement of d-from object is that it be easy to delete and () reassign. Compiler-Generated Move Constructor If we do provide a or / or /, then the compiler will generate a for us: based on memberwise simple data members: bitwise pointer members: bitwise member objects: uses members' / s inherited members: uses base class's / U Waterloo CS247 (Spring 2017) p.11/20 U Waterloo CS247 (Spring 2017) p.12/20
Move is similar to the, except that the destination of the already exists. Only requirement of d-from object is that it be easy to delete and () reassign. MyClass& MyClass::operator= (MyClass&& m) { MyClass temp(0); swap( temp, m ); // temp steals m s contents swap( *this, temp ); // put what used to be in // m into this Move Assignment Improved Assignment We can improve the code by passing the argument by value and unifying the and operators into a single member method. Compiler will call this operator even with an rvalue. MyClass::MyClass( const MyClass & other) : MyClass(0) { ( *this, other ); MyClass::MyClass( MyClass && other ) : MyClass(0) { swap( *this, other ); MyClass& MyClass::operator= (MyClass m) { swap( *this, m ); U Waterloo CS247 (Spring 2017) p.13/20 U Waterloo CS247 (Spring 2017) p.14/20 Compiler-Generated Move Assignment If we do provide a / or /, the compiler will create a operator= member function for us: based on memberwise : simple data members: bitwise pointer members: bitwise member objects: uses members' / inherited members: uses base class's / = ; // shallow U Waterloo CS247 (Spring 2017) p.15/20 http://accu.org/content/conf2014/howard_hinnant_accu_2014.pdf Special Members declares Nothing Any compiler implicitly declares deleted deleted deleted deleted
http://accu.org/content/conf2014/howard_hinnant_accu_2014.pdf Special Members declares Nothing Any compiler implicitly declares deleted deleted deleted deleted Deep equality Shallow equality Equality A copied/assigned object should be equal ( operator== ) to the original. compares compares The compiler does NOT generate a version of the equality operator we are on our own. U Waterloo CS247 (Spring 2017) p.18/20 Equality bool operator== ( const MyClass &m, const MyClass &m2 ) { if (!( Base::operator==(m, m2) ) ) return false; Take Aways Recognition C++ special member functions (6 of them): if one needs to be hand-crafted, likely all of them do if ( m.!= m2. ) return false; if (! (m. == m2.) ) return false; if (! m.p_ &&! m2.p_ ) return true; if (! m.p_! m2.p_ ) return false; return *m.p_ == *m2.p_ ; U Waterloo CS247 (Spring 2017) p.19/20 Comprehension Best practices for ADT design Entity vs. Value-based ADTs Rules for compiler- special member functions (,,, ) Application Operator overloading Const function arguments and member functions ADT design (entity vs. value-based design, immutable ADTs, hidden implementation) User-defined s,,, U Waterloo CS247 (Spring 2017) p.20/20