I don't quite get how the function pointer is getting set inside the struct in the g_instanceList[]
Instance
is an aggregate type. It may have a member function, but that doesn't make it not an aggregate. In C++98/03, objects of aggregate types can be initialized with aggregate initialization:
struct Aggregate
{
int x;
int y;
};
Aggregate agg = { 5, 4 };
assert(4 == agg.y); //Will be true.
Each member in the struct is initialized with each individual value, in the order in which those members are declared in the struct. The 5 goes into x
and the 4 goes into y
.
Instance
is an aggregate. And it has exactly one member. That member happens to be a function pointer type, but C++ doesn't care; it's a value and it can be used in aggregate initialization.
A C++ array is an aggregate as well. So you can initialize an array with aggregate initialization:
int arr[4] = {3, 45, 9, 81};
C++ also lets you initialize an array with aggregate initialization, where the size of the array is determined by the initializer:
int arr[] = {5, 2};
//arr will have 2 elements.
Therefore, g_instanceList
is an array, and therefore an aggregate which is subject to aggregate initialization. It has a size that will be determined by the number of values provided by the aggregate initialization syntax. Each element of the array is also an aggregate, so each element of the array can therefore be aggregate initialized.
Instance g_instanceList[] =
{
{StationaryOffset},
{OvalOffset},
{BottomCircleOffset},
};
Each member of the aggregate initialization list is itself an aggregate initialization which initializes an Instance
object. StationaryOffset
and the rest are function pointers which match the signature of the member of Instance
. So that's how Instance::CalcOffset
gets filled in.
how this g_instanceList is used in the next segment here
How it gets used is pretty common C++. The first line gets a reference to one of the Instance
array elements. This is done just to make the code shorter; it doesn't have to use g_instanceList[iLoop]
every time to talk about the Instance
it's using. The second line calls the member function of Instance
(which itself calls the internal function pointer), storing the result in a variable.
If you're talking about ARRAY_COUNT
, that's just a convenient macro to get... well, the count of the array elements. The C++ compiler knows how big g_instanceList
is, so the macro is used to make the compiler compute it itself. That way, if the g_instanceList
array length changes, you don't have to go through the entire codebase to find every use of the array's length. Also, you never have to directly state the length; you can infer it through aggregate initialization.