This post considers a specific example, the challenge of initializing arrays of objects in C++.
In C one could do this...
struct sD2 {
int x;
int y;
};
sD2 sd2[][3] = { {0,0}, {0,1}, {0,2} },
{1,0}, {1,1}, {1,2} },
};
It was concise, clear, and easy to expand. Note the unused last comma, so cutting & pasting a new row is flawless.
Initializing arrays of objects is more awkward because a constructor must be called explicitly. The closest I’ve found in C++ is the following...
class withLongName {
public:
int x;
int y;
withLongName () {} // Default ctor so withLongName a[5]; compiles.
withLongName (int x_, int y_) : x(x_), y(y_) {} // 2-arg ctor.
};
#define withLongName C
withLongName wlnc[][3] = { { C(0,0), C(0,1), C(0,2) },
{ C(1,0), C(1,1), C(1,2) },
};
#undef C
Without the defines, the table easily expands past the window width and adds typographic clutter to the initialization...
withLongName lnc[][3] = { { withLongName(0,0), withLongName(0,1), withLongName(0,2) },
{ withLongName(1,0), withLongName(1,1), withLongName(1,2) },
};
One could use ‘D’ for data, or ‘I’ for initialization, or others, but I think I like ‘C’ for constructor. I don’t care for the extra preprocessor lines, but if one specs a struct to initialize, then respecs it as the body of the class, and loads the object from the struct, one has both duplicated info, separation of variables from their initialization values, and even more extra lines.
class withLongName {
public:
int x;
int y;
withLongName () {} // Default ctor so withLongName a[5]; compiles.
withLongName (int x_, int y_) : x(x_), y(y_) {} // 2-arg ctor.
};
#define withLongName C
withLongName wlnc[][3] = { { C(0,0), C(0,1), C(0,2) },
{ C(1,0), C(1,1), C(1,2) },
};
#undef C
Without the defines, the table easily expands past the window width and adds typographic clutter to the initialization...
withLongName lnc[][3] = { { withLongName(0,0), withLongName(0,1), withLongName(0,2) },
{ withLongName(1,0), withLongName(1,1), withLongName(1,2) },
};
One could use ‘D’ for data, or ‘I’ for initialization, or others, but I think I like ‘C’ for constructor. I don’t care for the extra preprocessor lines, but if one specs a struct to initialize, then respecs it as the body of the class, and loads the object from the struct, one has both duplicated info, separation of variables from their initialization values, and even more extra lines.
Robert Tadlock tested this strategy and found that it avoided the typical inefficiencies of calling both the default constructor and another one, or of creating temporary objects subsequently destroyed in the initialization process.
No comments:
Post a Comment