Initializing an Array of Pointers to a Class
June 7, 2004
Arrays and pointers, despite having a tendency to become very confusing at times, are extremely useful tools, especially if you care at all about memory efficiency. Why store two copies of the same structure in memory when you can just pass a pointer?
There are hundreds of pages with tutorials about pointer and array usage and interchangablilty, each with a list of exercies and examples of common situations. But despite all these sites, I was unable to find a solution to my problem: How to properly initialize a variable-sided array of class pointers. If you have a basic understanding of pointers and arrays this doesn’t sound so hard but the notation can be tricky.
Consider a program with two classes: Road
and Car
. A Road
contains an
array of pointers to Car
s which is indexed by the Car
’s position along
the Road
. For example, suppose Road shepherd
is 10 units long and
contains two Car
s, bmw
and toyota
, at positions 0 and 4 respectively.
Then the indexing array, car_positions
, contains all null pointers with the
exception of car_positions[0] = &bmw
(the address of bmw
), and
car_positions[4] = &toyota
(the address of toyota
).
class Road {
private:
Car **car_positions;
// ...
public:
int length;
Road();
// ...
}
class Car {
private:
// ...
public:
int position;
Car(char*);
char name[];
// ...
}
It may seem obvious in this case to initialize the array with
CCar *car_positions[10]
, but what if the length of a Road
is unknown until
it is instantiated? I wasn’t sure how to do this. Normally, say for a string,
I would do something like the following:
void Car::Car(char *_name) {
name = new char[strlen(_name)+1];
strcpy(name,_name);
}
Here, new
allocates enough memory for the char
array because the size is
known. The Car
problem is different because car is not a built-in type and
we don’t want to immediately instantiate all 10 of the Car
s, only free
enough memory for 10 pointers to Car
s.
I had to abandon my web search with no results and I was left to
trial and error. At first I tried things like
car_positions = new *Car[10]
and car_positions = new Car*[10]
with
no luck. The trick to make C++ understand what type of array you want
is to simply put parenthesis around it. (Car*)
is a
pointer to class Car
. The solution:
void Road::Road() {
// ...
length = 10;
car_positions = new (Car*)[length];
// ...
}