SUBTOPICS
|
- Notes - Big and small objects
|
|
Notes on reference counting
When using RAVL for the first time, you'll find there's a few surprises,
such as when dealing with BIG and SMALL objects.
This page will give details on:
The distinction between Big and Small objects
Copying nested templated big objects
The main difference is in the way the assignment operator and copy
constructor work. Small objects behave like basic 'C++' types, in
that a new instance of the object is created with every new variable
and a full copy with each assignment operation. Big objects behave
more like pointers: assignment only copies the pointer to the body of
the class. This allows you to have more than one handle to a class.
The object itself is stored in the heap. All the problems of
allocating and deallocating space on the heap are invisibly handled
for you.
This may seem a bit confusing so here's an example:
int x,y; // Create two variables.
x = 2; // Assign the value 2 to x.
y = x; // Copy x to y.
y++; // Increment y.
As you would expect this code fragment leaves with x == 2 and y == 3.
Now let's use an integer array from RAVL:
Array1d<int> x(1),y(1); // Create a one element array.
x[0] = 2; // Assign value 2 to first element.
y = x; // x and y are now handles to the same object.
y[0]++; // This is now the same as x[0]++
This code leaves x[0] == 3 and y[0] == 3. If you wish assignment to make an
actual copy of the object you must do so explicitly:
Array1dC<int> x(1),y(1); // Create a one element array.
x[0] = 2; // Assign value 2 to first element.
y = x.Copy(); // y is now a copy of x.
y[0]++;
This behaves as the first example leaving with x == 2 and y == 3. Using the
copy constructor with big objects behaves in exactly the same was as the
assignment operator.
Array1dC<int> x(1); // Create a one element array.
Array1dC<int> y(x); // Create y with copy constructor.
x[0] = 2; // Assign value 2 to first element of x.
y[0]++; // x[0] is now equal to 3.
A typical example of big objects are VectorC, MatrixC, DListC and ImageC.
Some small objects are Vector2dC and Matrix2d2C.
If you are wondering when you should use a big object when writing a class yourself, here are some notes from Charles.
Copying nested templated big objects
What happens if I use the Copy()
function to copy for example an
array of images? - like this:
Array1dC<ImageC<RealT> > a1(6), a2;
.... // initialise the images in a1
....
a2 = a1.Copy();
....
What exactly gets copied here? In fact only the array gets copied, not the
images themselves; i.e. you get a new array in a2
which contains
pointers to the original images in a1
. If you want a "deep" copy,
so that all of the images in the array get copied into new images, you have to
do it explicitly:
a2 = a1.Copy();
for (IndexC i=a1.IMin(); i<=a1.IMax(); ++i) a2[i] = a1[i].Copy();
(If you have a large array, you can do the iteration more efficiently using an
array iterator, in this case Array1dIter2C
.)