// The rule of three: If you write ANY of: // • copy ctor // • assignment operator // • dtor // then you probably have to write all three. // // The rule of five: If you write ANY of: // • copy ctor // • assignment operator // • move ctor // • move assignment operator // • dtor // then you probably have to write all of them. #include #include #include using namespace std; class Thousand { public: Thousand() = default; // copy ctor Thousand(const Thousand &rhs) { *this = rhs; // Keep it DRY. } // assignment operator // Copy the data from the other object. We already have memory, // so just copy the count & the data itself. Thousand& operator=(const Thousand &rhs) { count = rhs.count; copy(rhs.data, rhs.data+count, data); // [start,end)⇒destination return *this; } // move ctor // Steal the data from the other object. Copy their count, // and just steal their pointer. Since this is a ctor, we had no // old data to dispose of. Thousand(Thousand &&rhs) : count(rhs.count), data(rhs.data) { rhs.data = nullptr; // We can’t both own the data. } // move assignment operator // Steal the data from the other object. Since this is assignment, // we’ve already allocated our own data. Rather than deleting our // data, we swap it to the other object, and let them delete it. Thousand& operator=(Thousand &&rhs) { swap(count, rhs.count); swap(data, rhs.data); return *this; } ~Thousand() { delete[] data; } [[nodiscard]] int size() const { return count; } [[nodiscard]] int& operator[](int n) { return data[n]; } [[nodiscard]] int operator[](int n) const { return data[n]; } void push_back(const int &datum) { assert(count<1000); data[count++] = datum; } private: int count = 0, *data = new int[1000]; }; int main() { Thousand t; t.push_back(11); t.push_back(22); t.push_back(33); cout << t[0] << ' ' << t[1] << ' ' << t[2] << '\n'; Thousand t2 = t; cout << t2[0] << ' ' << t2[1] << ' ' << t2[2] << '\n'; }