% lec 11: rule of three # administrivia ex10 due Wednesday ex11 due next Monday (_not_ this Friday) midterm review Thursday midterm exam Friday, here # feedback paper readings: too difficult? too boring? too long? too many unfamiliar terms? # tool clang-format -style Google -i ```c++ // bad input # include int main() { std::cout << "hello world\n"; return 0; } ``` ```c++ // bad input #include int main() { std::cout << "hello world\n"; return 0; } ``` # gcc 4.9+ colors ```c export GCC_COLORS=1 ``` run it in bash or add it to your bash profile gcc 4.9+ will then show colored warnings/errors # today's plan destructor copy constructor copy assignment operator (next week: rule of zero) # vector revisited start from [lec 4: vector v0](l04-ds.html#/vector-v0), goal: [vector.cc](l11/vector.cc) ```c++ #include typedef int T; struct vector { size_t size; T *data; }; int main(void) { size_t n = 10; vector v; v.size = n; std::cout << v.size << std::endl; std::cout << v.data << std::endl; } ``` # exercises initial value of `v`? default constructor (value undefined) change `struct` to `class` add constructor (new T[n] with initial_value) & size() & data() default arguments operator overloading [] explicit vs implicit constructor initialization lists range-based loop: define `begin()` & `end()` # destructor [vector_nodtor.cc](l11/vector_nodtor.cc) without destructor, valgrind reports memory leaks `delete` vs `delete[]` - valgrind again # shallow copy . . . ``` {.ditaa #l11/shallow} v +-------+ +-----+ | size_ | +---->| ... | +-------+ | +-----+ | data_ |----+ +-------+ | | new_v | +-------+ | | size_ | | +-------+ | | data_ |----+ +-------+ ``` # deep copy ``` {.ditaa #l11/deep} v +-------+ +-----+ | size_ | +---->| ... | +-------+ | +-----+ | data_ |----+ +-------+ new_v +-------+ +-----+ | size_ | +---->| ... | +-------+ | +-----+ | data_ |----+ +-------+ ``` # copy constructor [vector_nocpctor.cc](l11/vector_nocpctor.cc) without copy constructor: double free be careful: shallow vs deep copy explicit vs implicit disable compiler-generated functions using `= delete;` # copy assignment operator [vector_noassgn.cc](l11/vector_noassgn.cc) without copy constructor: leak & double free be careful again: shallow vs deep copy self assignment # sum up: syntax craziness ```c++ vector v0; // default constructor vector v0a = 10; // constructor (implicit) vector v0b(10); // constructor (explicit) vector v1 = v0; // copy constructor (implicit) vector v2(v0); // copy constructor (explicit) vector v3; v3 = v0; // copy assignment operator ``` [vector.cc](l11/vector.cc) # rule of three if you define one of - destructor - copy constructor - copy assignment operator you probably should define all three of them! reason: the compiler-generated version won't work # move semantics ```c++ vector foo(size_t n) { vector v(n); return v; } ``` ```c++ vector new_v(v); ``` return `vector` from a function? copy constructor is heavy-weight return a reference? lifetime problem. use a reference to hold the value? compile error. return value optimization (RVO): try `-fno-elide-constructors` rule of five: move constructor & move assignment operator # move semantics ``` {.ditaa #l11/move} v +-------+ +-----+ | 0 | +---->| ... | +-------+ | +-----+ |nullptr| | +-------+ | | new_v | +-------+ | | size_ | | +-------+ | | data_ |----+ +-------+ ``` # self-exercise 1 modify your 3D Point class from [lec 9 exercise 1](l09-class.html#/self-exercise-1) - disable the copy constructor and copy assignment operator - attempt to use copy & assign in code, and see what error the compiler generates - write a `CopyFrom()` member function, and try using it instead [soln](l11/exercise1/) # self-exercise 2 write a C++ class that: - is given the name of a file as a constructor argument - has a "GetNextWord()" method that returns the next whitespace or newline-separate word from the file as a copy of a "string" object, or an empty string once you hit EOF. - has a destructor that cleans up anything that needs cleaning up [soln](l11/exercise2/) # self-exercise 3 Write a C++ function that: - uses `new` to dynamically allocate an array of strings - uses `delete[]` to free it - uses new to dynamically allocate an array of pointers to strings - and then iterates through the array to use new to allocate a string for each array entry and to assign to each array element a pointer to the associated allocated string - and then uses `delete` to delete each allocated string - and then uses `delete[]` to delete the string pointer array [soln](l11/exercise3.cc) # see you on Wednesday C++ object model; `virtual` revisited