ulfben

The big five / writing resource owning classes

Nov 13th, 2018
107
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <algorithm>
  3. class Leon
  4. {
  5. public:
  6.     int* data = nullptr; //default member initialization
  7.     int length = 0;
  8.     //default construction (container-friendly!)
  9.     Leon() {}
  10.     //custom construction. Single argument constructor should always be explicit!
  11.     explicit Leon(int length) : data(new int[length]), length(length){  }
  12.     //copy construction
  13.     Leon(const Leon& other) : data(new int[other.length]), length(other.length) {
  14.         std::copy(other.data, other.data + other.length, data);
  15.     }
  16.     //move constructor
  17.     Leon(Leon&& other) {
  18.         data = other.data;
  19.         length = other.length;
  20.         other.data = nullptr;
  21.         other.length = 0;
  22.     }
  23.     //copy-assignment
  24.     Leon& operator= (const Leon& other) {
  25.         if (&other == this) {
  26.             return *this;
  27.         }
  28.         if (nullptr != data) {
  29.             delete[] data;
  30.         }
  31.         length = other.length;
  32.         data = new int[other.length];
  33.         std::copy(other.data, other.data + other.length, data);
  34.         return *this;
  35.     }
  36.     Leon& operator= (Leon&& other){
  37.         std::swap(other.length, length);
  38.         std::swap(other.data, data);
  39.         return *this;
  40.     }
  41.     ~Leon() {
  42.         if (nullptr != data){
  43.             delete[] data;
  44.         }
  45.     }
  46. };
  47. //argument by copy, return value by copy. Potentially large objects, expensive!
  48. Leon doSomethingExpensive(Leon p_leon) {
  49.     return p_leon; //will copy (expensive!) but *can* move, if available! (RVO almost always saves us though)
  50. }
  51. int main(int argc, int* argv[]){
  52.     Leon a;     //default constructible == container support
  53.     Leon b(10); //custom construction (explicit!)
  54.     Leon c(b);  //copy construction
  55.     Leon d(20);    
  56.     d = b; //copy assignment (remember to clean out the content of d!)
  57.     d = doSomethingExpensive(b); //b is an lvalue (named!) so it will be copied to the argument
  58.     d = doSomethingExpensive(Leon(50)); //Leon is an rvalue (no name!), and will *move* to the argument if the move constructor exist
  59.     d = std::move(b); //move-assign - give d the content of b, if move assignment operator exists.
  60.             // b is left valid but undefined (don't use after move!)
  61.     return 0;
  62. }
  63.  
  64. //Here is an ideal implementation of the big five:
  65.     // https://stackoverflow.com/a/12653520
  66. // notice how beautifully short and compact the boiler plate can be. :)
  67. // especially this neat hack: instead of writing two assignment operators,
  68. // you could write just one that takes its argument by value. That one can
  69. // be used for both copy and move assignment!
RAW Paste Data