Though its not the conceptual reason, i believe you can justify for yourself private class members by considering the risks and dangers associated with handling using the heap.
You can also instantly appreciate how usefull classes are, for example: Say you had an array but didnt know the size until runtime, during which it could change, you would be doing things like this:
int *items = 0;
. . .
items = new items[num_items];
/*Somwhere along, you realise you need to add another item:*/
/*copy array: note that i would never use the above code, nor even c equivelant with memcpy unless i was wanting platform independance to the extent of writing some code for a new age non embedded microwave oven processors compiler ..*/
++num_items;
int *copy = new items[num_items];
for( int t=0; t<num_items-1; ++t )
// Make a copy of the allocation with one more element added
{
copy[t] = items[t];
}
delete[]items; // delete old copy thats too small:
items = copy; // now allow items to be used the same, only one more item.
Of course you dont want to write the above code all the time: Its risky and not the prettiest thing: Classes can wrap these kinds of things and make them easy to deal with.
For example, the standard template library already has a class to perform this kind o functionality: std::vector.
#include<vector>
...
std::vector< int > items;
items.push_back( 4 ); // 'array' now looks like so: { 4 }
items.push_back( 22 ); //array now looks like so: { 4, 22 }
items.push_back( 1 ); // .... { 4, 22, 1 }
items.resize( 5 ); // { 4, 22, 1, ?, ? } ? as in dont know what that value would be: It would take on the value of whatever was previously at that variables position in the heap.
items [ 0 ] = 566; // { 566, 22, 1, ?, ? }
items[ 4 ] = -80; // { 566, 22, 1, ?, 80 }
items.pop_back(); // { 566, 22, 1, ? }
items.clear(); // {} ie empty.
Of course, then you might think that thats going to be doing alot of allocating and deallocating all the time, playing around with the heap more than you'd like. That does happen.
That is where linked containers come in (a container is an abstract data type ie class, that holds a number of objects and provides particular access and storage requirements: For example, vector stores them as a dynamic array, allows you to add and remove from the back and provides fast array like access).
With a list however (yes, theres <list> and std::list just like <vector> ), it stores information on where the variables are instead of reallocating like an array. So when you add a new object into the container, it can add it on/allocate it withought reallocating/changing the positions of the other values in the list.
To learn more about linked lists (no matter how far you have to leap, as long as your strong with pointer syntax, you migh just be ble to scrape past these concepts and learn a great deal), heres a tutorial which i learned (Had to look back into me old IE favourites lol)
http://www.gamedev.net/reference/articles/article2041.aspIts more of a C style: In C++ you'd be wrapping that stuff in a class, but to work on it this way first is a fundamental educational step IMO.
Practicing making these things for yourself is very important, even though when working on a big project though, its better to rely on the tried and tested standard code.
DMA and writing a linked list was the first thing i done when i started C++.
I wrote all the code for each list explicitly, rather than making or using classes to do those things, so when i grew to appreciate classes and templates i could literally be excited
.
Heres an analogy that will get you thinking about DMA.
Say there was a Bitmap class.
You dont need DMA right? If you want one Bitmap, you just go:
Bitmap bitmap;
bitmap.load( "bitmap.bmp" ); //Note these classes dont actually exist lol.
Wrong, as youll have guessed before you read 'Wrong' just there, if anything ive said has made sense.
The bitmaps data itself MUST be dynamically allocated.
Can you imagine a world where the size of every bitmap used by a program must be known at compile time?
Say we had an object called a 'Pixel'
A bitmap needs width*height pixels: simple rectangles area calculation.
So, withion that Bitmap class, when you call 'load' it reads the bitmaps width, and reads its height, and then it MUST Go:
internalPixelArray = new Pixel [ width*height ];
There is absolutely no way you can deny that requirement.
Allocate an array for the size of the biggest posible bitmap you'd have and then store the number of pixels that you actually use? That would be disgusting in several ways: Use up far too much memory: involve lots of checks: severly limit the size of your bitmap.
You could even have a big array: a 'pool' of sorts, and 'allocate' from your pool, one bitmap to have space from index 0 to 400 and another space 400 to 700. But why would you want to deal with that when youve got a dynamic heap that deals with and equivelant system, result wise for you in a far more elegant manner?
Note that when i say 'result wise' i am not considering the time and efficiency, just that the same result is eventually obtained.
Obvious programming concept: If one method takes 10 times longer than the other, generally the choice is obvious as to which one to use (though for many many reasons its never that simple, even in a simple for loop).