Step 3 of 8
RAII
RAII stands for "Resource Acquisition Is Initialization". It's an awkward name for the most important idea in C++:
Tie every resource to an object. Acquire it in the constructor, release it in the destructor.
Because destructors always run when the object goes away, the resource is always released: on normal exit, early return, or an exception. You can't forget, and you can't get the order wrong. Memory, files, locks, network connections and database transactions are all managed this way.
new and delete
C++'s versions of malloc and free:
new T(args)creates one object on the heap and returns a pointer;delete pdestroys it.new T[n]creates an array;delete[] pdestroys it. Mixing them up (deleteon an array) is undefined behavior.new int[n](): the()zero-initializes the elements.
Unlike malloc, new runs constructors and delete runs destructors.
#include <iostream>
class Buffer {
public:
explicit Buffer(int n) : data_(new double[n]()), n_(n) {
std::cout << "allocated " << n_ << "\n";
}
~Buffer() {
delete[] data_;
std::cout << "freed " << n_ << "\n";
}
double& at(int i) { return data_[i]; }
int size() const { return n_; }
private:
double* data_;
int n_;
};
int main() {
Buffer b(3);
b.at(0) = 1.5;
b.at(2) = b.at(0) * 2;
std::cout << b.at(0) + b.at(1) + b.at(2) << "\n";
}
allocated 3
4.5
freed 3
main never calls delete. The Buffer owns its array and frees it in its destructor.
Returning a reference
double& at(int i) returns a reference to the element, so b.at(0) = 1.5 writes into the array. Returning double would return a copy, and the assignment would change the copy.
Your turn: finish IntArray: the destructor, plus int size() const, int& at(int i) (returns a reference so callers can write through it) and int sum() const.