Initializing Arrays and Aggregates
Jordy posted a question to MSDN’s new forums website that I thought would be interesting to readers of my blog. Basically he wants to convert the following native C++ code to managed code:
class Constant
{
public:
String Name;
double Value;
};
static const Constant ConstTable[] =
{
{ "e", 2.718281828 },
{ "Pi", 3.14159265358979323846 },
{ "c", 299792458.0 }
};
There are a few aspects to this code that are worth noting as we look for a managed alternative:
- The ConstTable declaration includes the static keyword which indicates that the array has static duration. It is also a global variable and as such will have internal linkage. Briefly this means that different instances of the ConstTable identifier will refer to the same identifier but only within the translation unit.
- The Constant class is an aggregate and can be initialized with a comma-separated list of values in curly braces. Aggregate types don’t have constructors, non-public member variables, base classes or virtual functions.
Here is a simple solution using managed code:
value class Constant
{
public:
String^ Name;
double Value;
};
ref struct StaticClass abstract sealed
{
static initonly array<const Constant>^ ConstTable =
{
{ "e", 2.718281828 },
{ "Pi", 3.14159265358979323846 },
{ "c", 299792458.0 }
};
};
A few things are worth noting: A value class is used for defining Constant since ref classes don’t qualify as aggregate types. Value classes are also more efficiently stored and accessed in memory and are stored continuously in the managed array. An abstract sealed class is used to house the static array since managed types cannot be global variables.
The storage and linkage options offered by native C++ are useful but can get tricky as applications are built from different libraries. The CLR provides a conceptually simpler model for defining types and variables even if not all of the flexibility of C++ is available to managed types.
© 2005 Kenny Kerr